| .. | .. |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Regulator driver for TPS65073 PMIC |
|---|
| 5 | 5 | * |
|---|
| 6 | | - * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/ |
|---|
| 6 | + * Copyright (C) 2009 Texas Instrument Incorporated - https://www.ti.com/ |
|---|
| 7 | 7 | * |
|---|
| 8 | 8 | * This program is free software; you can redistribute it and/or |
|---|
| 9 | 9 | * modify it under the terms of the GNU General Public License as |
|---|
| .. | .. |
|---|
| 115 | 115 | struct tps6507x_pmic { |
|---|
| 116 | 116 | struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; |
|---|
| 117 | 117 | struct tps6507x_dev *mfd; |
|---|
| 118 | | - struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; |
|---|
| 119 | 118 | struct tps_info *info[TPS6507X_NUM_REGULATOR]; |
|---|
| 120 | 119 | struct mutex io_lock; |
|---|
| 121 | 120 | }; |
|---|
| .. | .. |
|---|
| 349 | 348 | return tps6507x_pmic_reg_write(tps, reg, data); |
|---|
| 350 | 349 | } |
|---|
| 351 | 350 | |
|---|
| 352 | | -static struct regulator_ops tps6507x_pmic_ops = { |
|---|
| 351 | +static const struct regulator_ops tps6507x_pmic_ops = { |
|---|
| 353 | 352 | .is_enabled = tps6507x_pmic_is_enabled, |
|---|
| 354 | 353 | .enable = tps6507x_pmic_enable, |
|---|
| 355 | 354 | .disable = tps6507x_pmic_disable, |
|---|
| .. | .. |
|---|
| 359 | 358 | .map_voltage = regulator_map_voltage_ascend, |
|---|
| 360 | 359 | }; |
|---|
| 361 | 360 | |
|---|
| 362 | | -static struct of_regulator_match tps6507x_matches[] = { |
|---|
| 363 | | - { .name = "VDCDC1"}, |
|---|
| 364 | | - { .name = "VDCDC2"}, |
|---|
| 365 | | - { .name = "VDCDC3"}, |
|---|
| 366 | | - { .name = "LDO1"}, |
|---|
| 367 | | - { .name = "LDO2"}, |
|---|
| 368 | | -}; |
|---|
| 369 | | - |
|---|
| 370 | | -static struct tps6507x_board *tps6507x_parse_dt_reg_data( |
|---|
| 371 | | - struct platform_device *pdev, |
|---|
| 372 | | - struct of_regulator_match **tps6507x_reg_matches) |
|---|
| 361 | +static int tps6507x_pmic_of_parse_cb(struct device_node *np, |
|---|
| 362 | + const struct regulator_desc *desc, |
|---|
| 363 | + struct regulator_config *config) |
|---|
| 373 | 364 | { |
|---|
| 374 | | - struct tps6507x_board *tps_board; |
|---|
| 375 | | - struct device_node *np = pdev->dev.parent->of_node; |
|---|
| 376 | | - struct device_node *regulators; |
|---|
| 377 | | - struct of_regulator_match *matches; |
|---|
| 378 | | - struct regulator_init_data *reg_data; |
|---|
| 379 | | - int idx = 0, count, ret; |
|---|
| 365 | + struct tps6507x_pmic *tps = config->driver_data; |
|---|
| 366 | + struct tps_info *info = tps->info[desc->id]; |
|---|
| 367 | + u32 prop; |
|---|
| 368 | + int ret; |
|---|
| 380 | 369 | |
|---|
| 381 | | - tps_board = devm_kzalloc(&pdev->dev, sizeof(*tps_board), |
|---|
| 382 | | - GFP_KERNEL); |
|---|
| 383 | | - if (!tps_board) |
|---|
| 384 | | - return NULL; |
|---|
| 370 | + ret = of_property_read_u32(np, "ti,defdcdc_default", &prop); |
|---|
| 371 | + if (!ret) |
|---|
| 372 | + info->defdcdc_default = prop; |
|---|
| 385 | 373 | |
|---|
| 386 | | - regulators = of_get_child_by_name(np, "regulators"); |
|---|
| 387 | | - if (!regulators) { |
|---|
| 388 | | - dev_err(&pdev->dev, "regulator node not found\n"); |
|---|
| 389 | | - return NULL; |
|---|
| 390 | | - } |
|---|
| 391 | | - |
|---|
| 392 | | - count = ARRAY_SIZE(tps6507x_matches); |
|---|
| 393 | | - matches = tps6507x_matches; |
|---|
| 394 | | - |
|---|
| 395 | | - ret = of_regulator_match(&pdev->dev, regulators, matches, count); |
|---|
| 396 | | - of_node_put(regulators); |
|---|
| 397 | | - if (ret < 0) { |
|---|
| 398 | | - dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", |
|---|
| 399 | | - ret); |
|---|
| 400 | | - return NULL; |
|---|
| 401 | | - } |
|---|
| 402 | | - |
|---|
| 403 | | - *tps6507x_reg_matches = matches; |
|---|
| 404 | | - |
|---|
| 405 | | - reg_data = devm_kzalloc(&pdev->dev, (sizeof(struct regulator_init_data) |
|---|
| 406 | | - * TPS6507X_NUM_REGULATOR), GFP_KERNEL); |
|---|
| 407 | | - if (!reg_data) |
|---|
| 408 | | - return NULL; |
|---|
| 409 | | - |
|---|
| 410 | | - tps_board->tps6507x_pmic_init_data = reg_data; |
|---|
| 411 | | - |
|---|
| 412 | | - for (idx = 0; idx < count; idx++) { |
|---|
| 413 | | - if (!matches[idx].init_data || !matches[idx].of_node) |
|---|
| 414 | | - continue; |
|---|
| 415 | | - |
|---|
| 416 | | - memcpy(®_data[idx], matches[idx].init_data, |
|---|
| 417 | | - sizeof(struct regulator_init_data)); |
|---|
| 418 | | - |
|---|
| 419 | | - } |
|---|
| 420 | | - |
|---|
| 421 | | - return tps_board; |
|---|
| 374 | + return 0; |
|---|
| 422 | 375 | } |
|---|
| 423 | 376 | |
|---|
| 424 | 377 | static int tps6507x_pmic_probe(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 426 | 379 | struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); |
|---|
| 427 | 380 | struct tps_info *info = &tps6507x_pmic_regs[0]; |
|---|
| 428 | 381 | struct regulator_config config = { }; |
|---|
| 429 | | - struct regulator_init_data *init_data; |
|---|
| 382 | + struct regulator_init_data *init_data = NULL; |
|---|
| 430 | 383 | struct regulator_dev *rdev; |
|---|
| 431 | 384 | struct tps6507x_pmic *tps; |
|---|
| 432 | 385 | struct tps6507x_board *tps_board; |
|---|
| 433 | | - struct of_regulator_match *tps6507x_reg_matches = NULL; |
|---|
| 434 | 386 | int i; |
|---|
| 435 | | - int error; |
|---|
| 436 | | - unsigned int prop; |
|---|
| 437 | 387 | |
|---|
| 438 | 388 | /** |
|---|
| 439 | 389 | * tps_board points to pmic related constants |
|---|
| .. | .. |
|---|
| 441 | 391 | */ |
|---|
| 442 | 392 | |
|---|
| 443 | 393 | tps_board = dev_get_platdata(tps6507x_dev->dev); |
|---|
| 444 | | - if (IS_ENABLED(CONFIG_OF) && !tps_board && |
|---|
| 445 | | - tps6507x_dev->dev->of_node) |
|---|
| 446 | | - tps_board = tps6507x_parse_dt_reg_data(pdev, |
|---|
| 447 | | - &tps6507x_reg_matches); |
|---|
| 448 | | - if (!tps_board) |
|---|
| 449 | | - return -EINVAL; |
|---|
| 450 | | - |
|---|
| 451 | | - /** |
|---|
| 452 | | - * init_data points to array of regulator_init structures |
|---|
| 453 | | - * coming from the board-evm file. |
|---|
| 454 | | - */ |
|---|
| 455 | | - init_data = tps_board->tps6507x_pmic_init_data; |
|---|
| 456 | | - if (!init_data) |
|---|
| 457 | | - return -EINVAL; |
|---|
| 394 | + if (tps_board) |
|---|
| 395 | + init_data = tps_board->tps6507x_pmic_init_data; |
|---|
| 458 | 396 | |
|---|
| 459 | 397 | tps = devm_kzalloc(&pdev->dev, sizeof(*tps), GFP_KERNEL); |
|---|
| 460 | 398 | if (!tps) |
|---|
| .. | .. |
|---|
| 465 | 403 | /* common for all regulators */ |
|---|
| 466 | 404 | tps->mfd = tps6507x_dev; |
|---|
| 467 | 405 | |
|---|
| 468 | | - for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { |
|---|
| 406 | + for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++) { |
|---|
| 469 | 407 | /* Register the regulators */ |
|---|
| 470 | 408 | tps->info[i] = info; |
|---|
| 471 | | - if (init_data->driver_data) { |
|---|
| 409 | + if (init_data && init_data[i].driver_data) { |
|---|
| 472 | 410 | struct tps6507x_reg_platform_data *data = |
|---|
| 473 | | - init_data->driver_data; |
|---|
| 474 | | - tps->info[i]->defdcdc_default = data->defdcdc_default; |
|---|
| 411 | + init_data[i].driver_data; |
|---|
| 412 | + info->defdcdc_default = data->defdcdc_default; |
|---|
| 475 | 413 | } |
|---|
| 476 | 414 | |
|---|
| 477 | 415 | tps->desc[i].name = info->name; |
|---|
| 416 | + tps->desc[i].of_match = of_match_ptr(info->name); |
|---|
| 417 | + tps->desc[i].regulators_node = of_match_ptr("regulators"); |
|---|
| 418 | + tps->desc[i].of_parse_cb = tps6507x_pmic_of_parse_cb; |
|---|
| 478 | 419 | tps->desc[i].id = i; |
|---|
| 479 | 420 | tps->desc[i].n_voltages = info->table_len; |
|---|
| 480 | 421 | tps->desc[i].volt_table = info->table; |
|---|
| .. | .. |
|---|
| 486 | 427 | config.init_data = init_data; |
|---|
| 487 | 428 | config.driver_data = tps; |
|---|
| 488 | 429 | |
|---|
| 489 | | - if (tps6507x_reg_matches) { |
|---|
| 490 | | - error = of_property_read_u32( |
|---|
| 491 | | - tps6507x_reg_matches[i].of_node, |
|---|
| 492 | | - "ti,defdcdc_default", &prop); |
|---|
| 493 | | - |
|---|
| 494 | | - if (!error) |
|---|
| 495 | | - tps->info[i]->defdcdc_default = prop; |
|---|
| 496 | | - |
|---|
| 497 | | - config.of_node = tps6507x_reg_matches[i].of_node; |
|---|
| 498 | | - } |
|---|
| 499 | | - |
|---|
| 500 | 430 | rdev = devm_regulator_register(&pdev->dev, &tps->desc[i], |
|---|
| 501 | 431 | &config); |
|---|
| 502 | 432 | if (IS_ERR(rdev)) { |
|---|
| .. | .. |
|---|
| 505 | 435 | pdev->name); |
|---|
| 506 | 436 | return PTR_ERR(rdev); |
|---|
| 507 | 437 | } |
|---|
| 508 | | - |
|---|
| 509 | | - /* Save regulator for cleanup */ |
|---|
| 510 | | - tps->rdev[i] = rdev; |
|---|
| 511 | 438 | } |
|---|
| 512 | 439 | |
|---|
| 513 | 440 | tps6507x_dev->pmic = tps; |
|---|