From 817bb7fbfb0a1ad5f9d475cef0752d4ec5fdeac2 Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Mon, 13 Aug 2012 20:36:05 +0530 Subject: mfd: Move tps65217 regulator plat data handling to regulator Regulator platform data handling was mistakenly added to MFD driver. So we will see build errors if we compile MFD drivers without CONFIG_REGULATOR. This patch moves regulator platform data handling from TPS65217 MFD driver to regulator driver. This makes MFD driver independent of REGULATOR framework so build error is fixed if CONFIG_REGULATOR is not set. drivers/built-in.o: In function `tps65217_probe': tps65217.c:(.devinit.text+0x13e37): undefined reference to `of_regulator_match' This patch also fix allocation size of tps65217 platform data. Current implementation allocates a struct tps65217_board for each regulator specified in the device tree. But the structure itself provides array of regulators so one instance of it is sufficient. Signed-off-by: AnilKumar Ch --- drivers/regulator/tps65217-regulator.c | 124 +++++++++++++++++++++++++++++---- 1 file changed, 109 insertions(+), 15 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77a..ab00cab905b7 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = { NULL), }; +#ifdef CONFIG_OF +static struct of_regulator_match reg_matches[] = { + { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, + { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, + { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, + { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, + { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, + { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, + { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, +}; + +static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) +{ + struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); + struct device_node *node = tps->dev->of_node; + struct tps65217_board *pdata; + struct device_node *regs; + int i, count; + + regs = of_find_node_by_name(node, "regulators"); + if (!regs) + return NULL; + + count = of_regulator_match(pdev->dev.parent, regs, + reg_matches, TPS65217_NUM_REGULATOR); + of_node_put(regs); + if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) + return NULL; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + for (i = 0; i < count; i++) { + if (!reg_matches[i].init_data || !reg_matches[i].of_node) + continue; + + pdata->tps65217_init_data[i] = reg_matches[i].init_data; + pdata->of_node[i] = reg_matches[i].of_node; + } + + return pdata; +} +#else +static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) +{ + return NULL; +} +#endif + static int __devinit tps65217_regulator_probe(struct platform_device *pdev) { + struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); + struct tps65217_board *pdata = dev_get_platdata(tps->dev); + struct regulator_init_data *reg_data; struct regulator_dev *rdev; - struct tps65217 *tps; - struct tps_info *info = &tps65217_pmic_regs[pdev->id]; struct regulator_config config = { }; + int i, ret; - /* Already set by core driver */ - tps = dev_to_tps65217(pdev->dev.parent); - tps->info[pdev->id] = info; + if (tps->dev->of_node) + pdata = tps65217_parse_dt(pdev); - config.dev = &pdev->dev; - config.of_node = pdev->dev.of_node; - config.init_data = pdev->dev.platform_data; - config.driver_data = tps; + if (!pdata) { + dev_err(&pdev->dev, "Platform data not found\n"); + return -EINVAL; + } - rdev = regulator_register(®ulators[pdev->id], &config); - if (IS_ERR(rdev)) - return PTR_ERR(rdev); + if (tps65217_chip_id(tps) != TPS65217) { + dev_err(&pdev->dev, "Invalid tps chip version\n"); + return -ENODEV; + } - platform_set_drvdata(pdev, rdev); + platform_set_drvdata(pdev, tps); + for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { + + reg_data = pdata->tps65217_init_data[i]; + + /* + * Regulator API handles empty constraints but not NULL + * constraints + */ + if (!reg_data) + continue; + + /* Register the regulators */ + tps->info[i] = &tps65217_pmic_regs[i]; + + config.dev = tps->dev; + config.init_data = reg_data; + config.driver_data = tps; + config.regmap = tps->regmap; + if (tps->dev->of_node) + config.of_node = pdata->of_node[i]; + + rdev = regulator_register(®ulators[i], &config); + if (IS_ERR(rdev)) { + dev_err(tps->dev, "failed to register %s regulator\n", + pdev->name); + ret = PTR_ERR(rdev); + goto err_unregister_regulator; + } + + /* Save regulator for cleanup */ + tps->rdev[i] = rdev; + } return 0; + +err_unregister_regulator: + while (--i >= 0) + regulator_unregister(tps->rdev[i]); + + return ret; } static int __devexit tps65217_regulator_remove(struct platform_device *pdev) { - struct regulator_dev *rdev = platform_get_drvdata(pdev); + struct tps65217 *tps = platform_get_drvdata(pdev); + unsigned int i; + + for (i = 0; i < TPS65217_NUM_REGULATOR; i++) + regulator_unregister(tps->rdev[i]); platform_set_drvdata(pdev, NULL); - regulator_unregister(rdev); return 0; } -- cgit v1.2.3 From 5656098e198e793f7b43a11c301b5025c6e51c9a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Aug 2012 19:42:47 +0100 Subject: mfd: wm831x: Convert to IORESOURCE_REG This was originally written by Russell King who unfortunately found himself unable to take the patch futher. Signed-off-by: Mark Brown Acked-by: Arnd Bergmann Acked-by: Haojian Zhuang Tested-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/wm831x-core.c | 66 ++++++++++++---------------------------- drivers/regulator/wm831x-dcdc.c | 12 ++++---- drivers/regulator/wm831x-isink.c | 4 +-- drivers/regulator/wm831x-ldo.c | 12 ++++---- 4 files changed, 34 insertions(+), 60 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 946698fd2dc6..2e5d58eb2ec1 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -614,18 +614,11 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg, } EXPORT_SYMBOL_GPL(wm831x_set_bits); -static struct resource wm831x_io_parent = { - .start = 0, - .end = 0xffffffff, - .flags = IORESOURCE_IO, -}; - static struct resource wm831x_dcdc1_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_DC1_CONTROL_1, .end = WM831X_DC1_DVS_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -644,10 +637,9 @@ static struct resource wm831x_dcdc1_resources[] = { static struct resource wm831x_dcdc2_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_DC2_CONTROL_1, .end = WM831X_DC2_DVS_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -665,10 +657,9 @@ static struct resource wm831x_dcdc2_resources[] = { static struct resource wm831x_dcdc3_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_DC3_CONTROL_1, .end = WM831X_DC3_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -680,10 +671,9 @@ static struct resource wm831x_dcdc3_resources[] = { static struct resource wm831x_dcdc4_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_DC4_CONTROL, .end = WM831X_DC4_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -695,10 +685,9 @@ static struct resource wm831x_dcdc4_resources[] = { static struct resource wm8320_dcdc4_buck_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_DC4_CONTROL, .end = WM832X_DC4_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -718,10 +707,9 @@ static struct resource wm831x_gpio_resources[] = { static struct resource wm831x_isink1_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_CURRENT_SINK_1, .end = WM831X_CURRENT_SINK_1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .start = WM831X_IRQ_CS1, @@ -732,10 +720,9 @@ static struct resource wm831x_isink1_resources[] = { static struct resource wm831x_isink2_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_CURRENT_SINK_2, .end = WM831X_CURRENT_SINK_2, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .start = WM831X_IRQ_CS2, @@ -746,10 +733,9 @@ static struct resource wm831x_isink2_resources[] = { static struct resource wm831x_ldo1_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO1_CONTROL, .end = WM831X_LDO1_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -761,10 +747,9 @@ static struct resource wm831x_ldo1_resources[] = { static struct resource wm831x_ldo2_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO2_CONTROL, .end = WM831X_LDO2_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -776,10 +761,9 @@ static struct resource wm831x_ldo2_resources[] = { static struct resource wm831x_ldo3_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO3_CONTROL, .end = WM831X_LDO3_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -791,10 +775,9 @@ static struct resource wm831x_ldo3_resources[] = { static struct resource wm831x_ldo4_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO4_CONTROL, .end = WM831X_LDO4_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -806,10 +789,9 @@ static struct resource wm831x_ldo4_resources[] = { static struct resource wm831x_ldo5_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO5_CONTROL, .end = WM831X_LDO5_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -821,10 +803,9 @@ static struct resource wm831x_ldo5_resources[] = { static struct resource wm831x_ldo6_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO6_CONTROL, .end = WM831X_LDO6_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -836,10 +817,9 @@ static struct resource wm831x_ldo6_resources[] = { static struct resource wm831x_ldo7_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO7_CONTROL, .end = WM831X_LDO7_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -851,10 +831,9 @@ static struct resource wm831x_ldo7_resources[] = { static struct resource wm831x_ldo8_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO8_CONTROL, .end = WM831X_LDO8_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -866,10 +845,9 @@ static struct resource wm831x_ldo8_resources[] = { static struct resource wm831x_ldo9_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO9_CONTROL, .end = WM831X_LDO9_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -881,10 +859,9 @@ static struct resource wm831x_ldo9_resources[] = { static struct resource wm831x_ldo10_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO10_CONTROL, .end = WM831X_LDO10_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, { .name = "UV", @@ -896,10 +873,9 @@ static struct resource wm831x_ldo10_resources[] = { static struct resource wm831x_ldo11_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_LDO11_ON_CONTROL, .end = WM831X_LDO11_SLEEP_CONTROL, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, }; @@ -998,19 +974,17 @@ static struct resource wm831x_rtc_resources[] = { static struct resource wm831x_status1_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_STATUS_LED_1, .end = WM831X_STATUS_LED_1, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, }; static struct resource wm831x_status2_resources[] = { { - .parent = &wm831x_io_parent, .start = WM831X_STATUS_LED_2, .end = WM831X_STATUS_LED_2, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_REG, }, }; diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index 7413885be01b..64111f4935a4 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c @@ -476,9 +476,9 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) dcdc->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } @@ -651,9 +651,9 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) dcdc->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } @@ -795,9 +795,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) dcdc->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index 0d207c297714..2646a1902b33 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c @@ -172,9 +172,9 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) isink->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index 5cb70ca1e98d..da73daf2eb7c 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c @@ -269,9 +269,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) ldo->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } @@ -520,9 +520,9 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) ldo->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } @@ -675,9 +675,9 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev) ldo->wm831x = wm831x; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource\n"); + dev_err(&pdev->dev, "No REG resource\n"); ret = -EINVAL; goto err; } -- cgit v1.2.3 From 023670295ab6b65f5a84b8f214377c04c683809d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Aug 2012 19:42:48 +0100 Subject: mfd: 88pm860x: Convert to IORESOURCE_REG Signed-off-by: Mark Brown Acked-by: Arnd Bergmann Acked-by: Haojian Zhuang Tested-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/leds/leds-88pm860x.c | 2 +- drivers/mfd/88pm860x-core.c | 92 +++++++++++------------------------ drivers/regulator/88pm8607.c | 2 +- drivers/video/backlight/88pm860x_bl.c | 2 +- 4 files changed, 32 insertions(+), 66 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c index 61897cfeeda6..ea2615b25082 100644 --- a/drivers/leds/leds-88pm860x.c +++ b/drivers/leds/leds-88pm860x.c @@ -197,7 +197,7 @@ static int pm860x_led_probe(struct platform_device *pdev) struct resource *res; int ret; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { dev_err(&pdev->dev, "No I/O resource!\n"); return -EINVAL; diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 220c79afe0bf..75864383573d 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -21,73 +21,40 @@ #define INT_STATUS_NUM 3 -static struct resource io_parent = { - .start = 0, - .end = 0xffffffff, - .flags = IORESOURCE_IO, -}; - static struct resource bk_resources[] __devinitdata = { - {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO, - &io_parent,}, - {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO, - &io_parent,}, - {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO, - &io_parent,}, + {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_REG,}, + {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_REG,}, + {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_REG,}, }; static struct resource led_resources[] __devinitdata = { - {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO, - &io_parent,}, - {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO, - &io_parent,}, - {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_IO, - &io_parent,}, - {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_IO, - &io_parent,}, - {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO, - &io_parent,}, - {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO, - &io_parent,}, + {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_REG,}, + {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_REG,}, + {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_REG,}, + {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_REG,}, + {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_REG,}, + {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_REG,}, }; static struct resource regulator_resources[] __devinitdata = { - {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO, - &io_parent,}, - {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO, - &io_parent,}, + {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_REG,}, + {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_REG,}, + {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_REG,}, + {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_REG,}, + {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_REG,}, + {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_REG,}, + {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_REG,}, + {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_REG,}, + {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_REG,}, + {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_REG,}, + {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_REG,}, + {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_REG,}, + {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_REG,}, + {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_REG,}, + {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_REG,}, + {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_REG,}, + {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_REG,}, + {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_REG,}, }; static struct resource touch_resources[] __devinitdata = { @@ -124,12 +91,11 @@ static struct resource charger_resources[] __devinitdata = { }; static struct resource preg_resources[] __devinitdata = { - {PM8606_ID_PREG, PM8606_ID_PREG, "preg", IORESOURCE_IO, - &io_parent,}, + {PM8606_ID_PREG, PM8606_ID_PREG, "preg", IORESOURCE_REG,}, }; static struct resource rtc_resources[] __devinitdata = { - {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ, &io_parent,}, + {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,}, }; static struct mfd_cell bk_devs[] = { diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index c3482b954cb7..0b76372aee72 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -320,7 +320,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) struct resource *res; int i; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { dev_err(&pdev->dev, "No I/O resource!\n"); return -EINVAL; diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index f75da8758adc..d65472e9b30d 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -201,7 +201,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev) char name[MFD_NAME_SIZE]; int ret; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { dev_err(&pdev->dev, "No I/O resource!\n"); return -EINVAL; -- cgit v1.2.3 From a70abacb06b884131ec181551a71ef325490f374 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 8 Aug 2012 23:17:28 +0800 Subject: mfd: 88pm860x: Use REG resource in regulator Since IORESOURCE_IO is changed to IORESOURCE_REG in 88pm860x driver, update self-defined IORESOURCE_IO resource to register offset that is IORESOURCE_REG in regulator driver. And split regulator platform data array into scattered platform data. Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-core.c | 265 ++++++++++++++++++++++++++++++++----------- drivers/regulator/88pm8607.c | 5 +- include/linux/mfd/88pm860x.h | 18 ++- 3 files changed, 217 insertions(+), 71 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index e364b22f957d..fca15be6c0d1 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -68,25 +68,53 @@ static struct resource led5_resources[] __devinitdata = { {0x8, 0x8, "blink", IORESOURCE_REG, }, }; -static struct resource regulator_resources[] __devinitdata = { - {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_REG,}, - {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_REG,}, - {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_REG,}, - {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_REG,}, - {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_REG,}, - {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_REG,}, - {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_REG,}, - {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_REG,}, - {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_REG,}, - {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_REG,}, - {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_REG,}, - {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_REG,}, - {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_REG,}, - {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_REG,}, - {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_REG,}, - {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_REG,}, - {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_REG,}, - {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_REG,}, +static struct resource buck1_resources[] __devinitdata = { + {0x24, 0x24, "buck set", IORESOURCE_REG, }, +}; +static struct resource buck2_resources[] __devinitdata = { + {0x25, 0x25, "buck set", IORESOURCE_REG, }, +}; +static struct resource buck3_resources[] __devinitdata = { + {0x26, 0x26, "buck set", IORESOURCE_REG, }, +}; +static struct resource ldo1_resources[] __devinitdata = { + {0x10, 0x10, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo2_resources[] __devinitdata = { + {0x11, 0x11, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo3_resources[] __devinitdata = { + {0x12, 0x12, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo4_resources[] __devinitdata = { + {0x13, 0x13, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo5_resources[] __devinitdata = { + {0x14, 0x14, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo6_resources[] __devinitdata = { + {0x15, 0x15, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo7_resources[] __devinitdata = { + {0x16, 0x16, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo8_resources[] __devinitdata = { + {0x17, 0x17, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo9_resources[] __devinitdata = { + {0x18, 0x18, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo10_resources[] __devinitdata = { + {0x19, 0x19, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo12_resources[] __devinitdata = { + {0x1a, 0x1a, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo_vibrator_resources[] __devinitdata = { + {0x28, 0x28, "ldo set", IORESOURCE_REG, }, +}; +static struct resource ldo14_resources[] __devinitdata = { + {0x1b, 0x1b, "ldo set", IORESOURCE_REG, }, }; static struct resource touch_resources[] __devinitdata = { @@ -183,25 +211,88 @@ static struct mfd_cell led_devs[] = { }, }; -static struct mfd_cell regulator_devs[] = { - {"88pm860x-regulator", 0,}, - {"88pm860x-regulator", 1,}, - {"88pm860x-regulator", 2,}, - {"88pm860x-regulator", 3,}, - {"88pm860x-regulator", 4,}, - {"88pm860x-regulator", 5,}, - {"88pm860x-regulator", 6,}, - {"88pm860x-regulator", 7,}, - {"88pm860x-regulator", 8,}, - {"88pm860x-regulator", 9,}, - {"88pm860x-regulator", 10,}, - {"88pm860x-regulator", 11,}, - {"88pm860x-regulator", 12,}, - {"88pm860x-regulator", 13,}, - {"88pm860x-regulator", 14,}, - {"88pm860x-regulator", 15,}, - {"88pm860x-regulator", 16,}, - {"88pm860x-regulator", 17,}, +static struct mfd_cell reg_devs[] = { + { + .name = "88pm860x-regulator", + .id = 0, + .num_resources = ARRAY_SIZE(buck1_resources), + .resources = buck1_resources, + }, { + .name = "88pm860x-regulator", + .id = 1, + .num_resources = ARRAY_SIZE(buck2_resources), + .resources = buck2_resources, + }, { + .name = "88pm860x-regulator", + .id = 2, + .num_resources = ARRAY_SIZE(buck3_resources), + .resources = buck3_resources, + }, { + .name = "88pm860x-regulator", + .id = 3, + .num_resources = ARRAY_SIZE(ldo1_resources), + .resources = ldo1_resources, + }, { + .name = "88pm860x-regulator", + .id = 4, + .num_resources = ARRAY_SIZE(ldo2_resources), + .resources = ldo2_resources, + }, { + .name = "88pm860x-regulator", + .id = 5, + .num_resources = ARRAY_SIZE(ldo3_resources), + .resources = ldo3_resources, + }, { + .name = "88pm860x-regulator", + .id = 6, + .num_resources = ARRAY_SIZE(ldo4_resources), + .resources = ldo4_resources, + }, { + .name = "88pm860x-regulator", + .id = 7, + .num_resources = ARRAY_SIZE(ldo5_resources), + .resources = ldo5_resources, + }, { + .name = "88pm860x-regulator", + .id = 8, + .num_resources = ARRAY_SIZE(ldo6_resources), + .resources = ldo6_resources, + }, { + .name = "88pm860x-regulator", + .id = 9, + .num_resources = ARRAY_SIZE(ldo7_resources), + .resources = ldo7_resources, + }, { + .name = "88pm860x-regulator", + .id = 10, + .num_resources = ARRAY_SIZE(ldo8_resources), + .resources = ldo8_resources, + }, { + .name = "88pm860x-regulator", + .id = 11, + .num_resources = ARRAY_SIZE(ldo9_resources), + .resources = ldo9_resources, + }, { + .name = "88pm860x-regulator", + .id = 12, + .num_resources = ARRAY_SIZE(ldo10_resources), + .resources = ldo10_resources, + }, { + .name = "88pm860x-regulator", + .id = 13, + .num_resources = ARRAY_SIZE(ldo12_resources), + .resources = ldo12_resources, + }, { + .name = "88pm860x-regulator", + .id = 14, + .num_resources = ARRAY_SIZE(ldo_vibrator_resources), + .resources = ldo_vibrator_resources, + }, { + .name = "88pm860x-regulator", + .id = 15, + .num_resources = ARRAY_SIZE(ldo14_resources), + .resources = ldo14_resources, + }, }; static struct mfd_cell touch_devs[] = { @@ -727,38 +818,80 @@ static void __devinit device_led_init(struct pm860x_chip *chip, static void __devinit device_regulator_init(struct pm860x_chip *chip, struct pm860x_platform_data *pdata) { - struct regulator_init_data *initdata; int ret; - int i, seq; - if ((pdata == NULL) || (pdata->regulator == NULL)) + if (pdata == NULL) + return; + if (pdata->buck1) { + reg_devs[0].platform_data = pdata->buck1; + reg_devs[0].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->buck2) { + reg_devs[1].platform_data = pdata->buck2; + reg_devs[1].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->buck3) { + reg_devs[2].platform_data = pdata->buck3; + reg_devs[2].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo1) { + reg_devs[3].platform_data = pdata->ldo1; + reg_devs[3].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo2) { + reg_devs[4].platform_data = pdata->ldo2; + reg_devs[4].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo3) { + reg_devs[5].platform_data = pdata->ldo3; + reg_devs[5].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo4) { + reg_devs[6].platform_data = pdata->ldo4; + reg_devs[6].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo5) { + reg_devs[7].platform_data = pdata->ldo5; + reg_devs[7].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo6) { + reg_devs[8].platform_data = pdata->ldo6; + reg_devs[8].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo7) { + reg_devs[9].platform_data = pdata->ldo7; + reg_devs[9].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo8) { + reg_devs[10].platform_data = pdata->ldo8; + reg_devs[10].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo9) { + reg_devs[11].platform_data = pdata->ldo9; + reg_devs[11].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo10) { + reg_devs[12].platform_data = pdata->ldo10; + reg_devs[12].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo12) { + reg_devs[13].platform_data = pdata->ldo12; + reg_devs[13].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo_vibrator) { + reg_devs[14].platform_data = pdata->ldo_vibrator; + reg_devs[14].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo14) { + reg_devs[15].platform_data = pdata->ldo14; + reg_devs[15].pdata_size = sizeof(struct regulator_init_data); + } + ret = mfd_add_devices(chip->dev, 0, reg_devs, + ARRAY_SIZE(reg_devs), NULL, 0); + if (ret < 0) { + dev_err(chip->dev, "Failed to add regulator subdev\n"); return; - - if (pdata->num_regulators > ARRAY_SIZE(regulator_devs)) - pdata->num_regulators = ARRAY_SIZE(regulator_devs); - - for (i = 0, seq = -1; i < pdata->num_regulators; i++) { - initdata = &pdata->regulator[i]; - seq = *(unsigned int *)initdata->driver_data; - if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) { - dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n", - seq, initdata->constraints.name); - goto out; - } - regulator_devs[i].platform_data = &pdata->regulator[i]; - regulator_devs[i].pdata_size = sizeof(struct regulator_init_data); - regulator_devs[i].num_resources = 1; - regulator_devs[i].resources = ®ulator_resources[seq]; - - ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, - ®ulator_resources[seq], 0); - if (ret < 0) { - dev_err(chip->dev, "Failed to add regulator subdev\n"); - goto out; - } } -out: - return; } static void __devinit device_rtc_init(struct pm860x_chip *chip, diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 0b76372aee72..843c89a15472 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -322,12 +322,12 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_REG, 0); if (res == NULL) { - dev_err(&pdev->dev, "No I/O resource!\n"); + dev_err(&pdev->dev, "No REG resource!\n"); return -EINVAL; } for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { info = &pm8607_regulator_info[i]; - if (info->desc.id == res->start) + if (info->desc.vsel_reg == res->start) break; } if (i == ARRAY_SIZE(pm8607_regulator_info)) { @@ -351,7 +351,6 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) else config.regmap = chip->regmap_companion; - /* replace driver_data with info */ info->regulator = regulator_register(&info->desc, &config); if (IS_ERR(info->regulator)) { dev_err(&pdev->dev, "failed to register regulator %s\n", diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index 2d042f972c68..87c933d1b912 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -359,7 +359,22 @@ struct pm860x_platform_data { struct pm860x_rtc_pdata *rtc; struct pm860x_touch_pdata *touch; struct pm860x_power_pdata *power; - struct regulator_init_data *regulator; + struct regulator_init_data *buck1; + struct regulator_init_data *buck2; + struct regulator_init_data *buck3; + struct regulator_init_data *ldo1; + struct regulator_init_data *ldo2; + struct regulator_init_data *ldo3; + struct regulator_init_data *ldo4; + struct regulator_init_data *ldo5; + struct regulator_init_data *ldo6; + struct regulator_init_data *ldo7; + struct regulator_init_data *ldo8; + struct regulator_init_data *ldo9; + struct regulator_init_data *ldo10; + struct regulator_init_data *ldo12; + struct regulator_init_data *ldo_vibrator; + struct regulator_init_data *ldo14; unsigned short companion_addr; /* I2C address of companion chip */ int i2c_port; /* Controlled by GI2C or PI2C */ @@ -367,7 +382,6 @@ struct pm860x_platform_data { int irq_base; /* IRQ base number of 88pm860x */ int num_leds; int num_backlights; - int num_regulators; }; extern int pm8606_osc_enable(struct pm860x_chip *, unsigned short); -- cgit v1.2.3 From 0fd0013cda05a3bbdaf861c9fdfe8496230da672 Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Fri, 10 Aug 2012 10:32:35 +0200 Subject: mfd: ab3100: Split ab3100 headers out of abx500.h The U8500 has its own set of separate header, so the abx500 becomes completely abstract. Do the same split for the AB3100 legacy ASIC. Signed-off-by: Marcus Cooper Signed-off-by: Linus Walleij Signed-off-by: Samuel Ortiz --- arch/arm/mach-u300/i2c.c | 2 +- drivers/mfd/ab3100-core.c | 1 + drivers/regulator/ab3100.c | 1 + include/linux/mfd/ab3100.h | 129 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/abx500.h | 117 +--------------------------------------- 5 files changed, 133 insertions(+), 117 deletions(-) create mode 100644 include/linux/mfd/ab3100.h (limited to 'drivers/regulator') diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c index cb04bd6ab3e7..4227b155a900 100644 --- a/arch/arm/mach-u300/i2c.c +++ b/arch/arm/mach-u300/i2c.c @@ -9,7 +9,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 01781ae5d0d7..2b3dde571a50 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* These are the only registers inside AB3100 used in this main file */ diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 182b553059c9..b6cde9c16c8f 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c @@ -15,6 +15,7 @@ #include #include #include +#include #include /* LDO registers and some handy masking definitions for AB3100 */ diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h new file mode 100644 index 000000000000..afd3080bde24 --- /dev/null +++ b/include/linux/mfd/ab3100.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2007-2009 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * AB3100 core access functions + * Author: Linus Walleij + * + */ + +#include + +struct device; + +#ifndef MFD_AB3100_H +#define MFD_AB3100_H + + +#define AB3100_P1A 0xc0 +#define AB3100_P1B 0xc1 +#define AB3100_P1C 0xc2 +#define AB3100_P1D 0xc3 +#define AB3100_P1E 0xc4 +#define AB3100_P1F 0xc5 +#define AB3100_P1G 0xc6 +#define AB3100_R2A 0xc7 +#define AB3100_R2B 0xc8 + +/* + * AB3100, EVENTA1, A2 and A3 event register flags + * these are catenated into a single 32-bit flag in the code + * for event notification broadcasts. + */ +#define AB3100_EVENTA1_ONSWA (0x01<<16) +#define AB3100_EVENTA1_ONSWB (0x02<<16) +#define AB3100_EVENTA1_ONSWC (0x04<<16) +#define AB3100_EVENTA1_DCIO (0x08<<16) +#define AB3100_EVENTA1_OVER_TEMP (0x10<<16) +#define AB3100_EVENTA1_SIM_OFF (0x20<<16) +#define AB3100_EVENTA1_VBUS (0x40<<16) +#define AB3100_EVENTA1_VSET_USB (0x80<<16) + +#define AB3100_EVENTA2_READY_TX (0x01<<8) +#define AB3100_EVENTA2_READY_RX (0x02<<8) +#define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8) +#define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8) +#define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8) +#define AB3100_EVENTA2_MIDR (0x20<<8) +#define AB3100_EVENTA2_BATTERY_REM (0x40<<8) +#define AB3100_EVENTA2_ALARM (0x80<<8) + +#define AB3100_EVENTA3_ADC_TRIG5 (0x01) +#define AB3100_EVENTA3_ADC_TRIG4 (0x02) +#define AB3100_EVENTA3_ADC_TRIG3 (0x04) +#define AB3100_EVENTA3_ADC_TRIG2 (0x08) +#define AB3100_EVENTA3_ADC_TRIGVBAT (0x10) +#define AB3100_EVENTA3_ADC_TRIGVTX (0x20) +#define AB3100_EVENTA3_ADC_TRIG1 (0x40) +#define AB3100_EVENTA3_ADC_TRIG0 (0x80) + +/* AB3100, STR register flags */ +#define AB3100_STR_ONSWA (0x01) +#define AB3100_STR_ONSWB (0x02) +#define AB3100_STR_ONSWC (0x04) +#define AB3100_STR_DCIO (0x08) +#define AB3100_STR_BOOT_MODE (0x10) +#define AB3100_STR_SIM_OFF (0x20) +#define AB3100_STR_BATT_REMOVAL (0x40) +#define AB3100_STR_VBUS (0x80) + +/* + * AB3100 contains 8 regulators, one external regulator controller + * and a buck converter, further the LDO E and buck converter can + * have separate settings if they are in sleep mode, this is + * modeled as a separate regulator. + */ +#define AB3100_NUM_REGULATORS 10 + +/** + * struct ab3100 + * @access_mutex: lock out concurrent accesses to the AB3100 registers + * @dev: pointer to the containing device + * @i2c_client: I2C client for this chip + * @testreg_client: secondary client for test registers + * @chip_name: name of this chip variant + * @chip_id: 8 bit chip ID for this chip variant + * @event_subscribers: event subscribers are listed here + * @startup_events: a copy of the first reading of the event registers + * @startup_events_read: whether the first events have been read + * + * This struct is PRIVATE and devices using it should NOT + * access ANY fields. It is used as a token for calling the + * AB3100 functions. + */ +struct ab3100 { + struct mutex access_mutex; + struct device *dev; + struct i2c_client *i2c_client; + struct i2c_client *testreg_client; + char chip_name[32]; + u8 chip_id; + struct blocking_notifier_head event_subscribers; + u8 startup_events[3]; + bool startup_events_read; +}; + +/** + * struct ab3100_platform_data + * Data supplied to initialize board connections to the AB3100 + * @reg_constraints: regulator constraints for target board + * the order of these constraints are: LDO A, C, D, E, + * F, G, H, K, EXT and BUCK. + * @reg_initvals: initial values for the regulator registers + * plus two sleep settings for LDO E and the BUCK converter. + * exactly AB3100_NUM_REGULATORS+2 values must be sent in. + * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK, + * BUCK sleep, LDO D. (LDO D need to be initialized last.) + * @external_voltage: voltage level of the external regulator. + */ +struct ab3100_platform_data { + struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS]; + u8 reg_initvals[AB3100_NUM_REGULATORS+2]; + int external_voltage; +}; + +int ab3100_event_register(struct ab3100 *ab3100, + struct notifier_block *nb); +int ab3100_event_unregister(struct ab3100 *ab3100, + struct notifier_block *nb); + +#endif /* MFD_AB3100_H */ diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h index 1318ca622633..5d5298d56026 100644 --- a/include/linux/mfd/abx500.h +++ b/include/linux/mfd/abx500.h @@ -1,12 +1,9 @@ /* * Copyright (C) 2007-2009 ST-Ericsson AB * License terms: GNU General Public License (GPL) version 2 - * AB3100 core access functions - * Author: Linus Walleij * * ABX500 core access functions. - * The abx500 interface is used for the Analog Baseband chip - * ab3100 and ab8500. + * The abx500 interface is used for the Analog Baseband chips. * * Author: Mattias Wallin * Author: Mattias Nilsson @@ -21,118 +18,6 @@ struct device; #ifndef MFD_ABX500_H #define MFD_ABX500_H -#define AB3100_P1A 0xc0 -#define AB3100_P1B 0xc1 -#define AB3100_P1C 0xc2 -#define AB3100_P1D 0xc3 -#define AB3100_P1E 0xc4 -#define AB3100_P1F 0xc5 -#define AB3100_P1G 0xc6 -#define AB3100_R2A 0xc7 -#define AB3100_R2B 0xc8 - -/* - * AB3100, EVENTA1, A2 and A3 event register flags - * these are catenated into a single 32-bit flag in the code - * for event notification broadcasts. - */ -#define AB3100_EVENTA1_ONSWA (0x01<<16) -#define AB3100_EVENTA1_ONSWB (0x02<<16) -#define AB3100_EVENTA1_ONSWC (0x04<<16) -#define AB3100_EVENTA1_DCIO (0x08<<16) -#define AB3100_EVENTA1_OVER_TEMP (0x10<<16) -#define AB3100_EVENTA1_SIM_OFF (0x20<<16) -#define AB3100_EVENTA1_VBUS (0x40<<16) -#define AB3100_EVENTA1_VSET_USB (0x80<<16) - -#define AB3100_EVENTA2_READY_TX (0x01<<8) -#define AB3100_EVENTA2_READY_RX (0x02<<8) -#define AB3100_EVENTA2_OVERRUN_ERROR (0x04<<8) -#define AB3100_EVENTA2_FRAMING_ERROR (0x08<<8) -#define AB3100_EVENTA2_CHARG_OVERCURRENT (0x10<<8) -#define AB3100_EVENTA2_MIDR (0x20<<8) -#define AB3100_EVENTA2_BATTERY_REM (0x40<<8) -#define AB3100_EVENTA2_ALARM (0x80<<8) - -#define AB3100_EVENTA3_ADC_TRIG5 (0x01) -#define AB3100_EVENTA3_ADC_TRIG4 (0x02) -#define AB3100_EVENTA3_ADC_TRIG3 (0x04) -#define AB3100_EVENTA3_ADC_TRIG2 (0x08) -#define AB3100_EVENTA3_ADC_TRIGVBAT (0x10) -#define AB3100_EVENTA3_ADC_TRIGVTX (0x20) -#define AB3100_EVENTA3_ADC_TRIG1 (0x40) -#define AB3100_EVENTA3_ADC_TRIG0 (0x80) - -/* AB3100, STR register flags */ -#define AB3100_STR_ONSWA (0x01) -#define AB3100_STR_ONSWB (0x02) -#define AB3100_STR_ONSWC (0x04) -#define AB3100_STR_DCIO (0x08) -#define AB3100_STR_BOOT_MODE (0x10) -#define AB3100_STR_SIM_OFF (0x20) -#define AB3100_STR_BATT_REMOVAL (0x40) -#define AB3100_STR_VBUS (0x80) - -/* - * AB3100 contains 8 regulators, one external regulator controller - * and a buck converter, further the LDO E and buck converter can - * have separate settings if they are in sleep mode, this is - * modeled as a separate regulator. - */ -#define AB3100_NUM_REGULATORS 10 - -/** - * struct ab3100 - * @access_mutex: lock out concurrent accesses to the AB3100 registers - * @dev: pointer to the containing device - * @i2c_client: I2C client for this chip - * @testreg_client: secondary client for test registers - * @chip_name: name of this chip variant - * @chip_id: 8 bit chip ID for this chip variant - * @event_subscribers: event subscribers are listed here - * @startup_events: a copy of the first reading of the event registers - * @startup_events_read: whether the first events have been read - * - * This struct is PRIVATE and devices using it should NOT - * access ANY fields. It is used as a token for calling the - * AB3100 functions. - */ -struct ab3100 { - struct mutex access_mutex; - struct device *dev; - struct i2c_client *i2c_client; - struct i2c_client *testreg_client; - char chip_name[32]; - u8 chip_id; - struct blocking_notifier_head event_subscribers; - u8 startup_events[3]; - bool startup_events_read; -}; - -/** - * struct ab3100_platform_data - * Data supplied to initialize board connections to the AB3100 - * @reg_constraints: regulator constraints for target board - * the order of these constraints are: LDO A, C, D, E, - * F, G, H, K, EXT and BUCK. - * @reg_initvals: initial values for the regulator registers - * plus two sleep settings for LDO E and the BUCK converter. - * exactly AB3100_NUM_REGULATORS+2 values must be sent in. - * Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK, - * BUCK sleep, LDO D. (LDO D need to be initialized last.) - * @external_voltage: voltage level of the external regulator. - */ -struct ab3100_platform_data { - struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS]; - u8 reg_initvals[AB3100_NUM_REGULATORS+2]; - int external_voltage; -}; - -int ab3100_event_register(struct ab3100 *ab3100, - struct notifier_block *nb); -int ab3100_event_unregister(struct ab3100 *ab3100, - struct notifier_block *nb); - /** * struct abx500_init_setting * Initial value of the registers for driver to use during setup. -- cgit v1.2.3 From baa64151aecccedbafae1bbc0c167c8b2a711752 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 5 Sep 2012 10:57:15 +0800 Subject: regulator: anatop-regulator: Convert to use syscon to access anatop register Using syscon to access anatop register. Acked-by: Mark Brown Acked-by: Stephen Warren Signed-off-by: Dong Aisheng Signed-off-by: Samuel Ortiz --- arch/arm/boot/dts/imx6q.dtsi | 4 +-- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/mach-imx6q.c | 47 ++++++++++++++---------------------- drivers/regulator/Kconfig | 2 +- drivers/regulator/anatop-regulator.c | 31 ++++++++++++++++-------- 5 files changed, 43 insertions(+), 43 deletions(-) (limited to 'drivers/regulator') diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index bea21bc1aadd..52ed4d1ff4ed 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -378,8 +378,8 @@ interrupts = <0 87 0x04 0 88 0x04>; }; - anatop@020c8000 { - compatible = "fsl,imx6q-anatop"; + anatop: anatop@020c8000 { + compatible = "fsl,imx6q-anatop", "syscon", "simple-bus"; reg = <0x020c8000 0x1000>; interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>; diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index afd542ad6f97..7bba253fd2bb 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -839,7 +839,7 @@ config SOC_IMX6Q select HAVE_IMX_MMDC select HAVE_IMX_SRC select HAVE_SMP - select MFD_ANATOP + select MFD_SYSCON select PINCTRL select PINCTRL_IMX6Q diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 5ec0608f2a76..8d7c14140744 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -24,8 +24,9 @@ #include #include #include +#include #include -#include +#include #include #include #include @@ -120,20 +121,7 @@ static void __init imx6q_sabrelite_init(void) static void __init imx6q_usb_init(void) { - struct device_node *np; - struct platform_device *pdev = NULL; - struct anatop *adata = NULL; - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); - if (np) - pdev = of_find_device_by_node(np); - if (pdev) - adata = platform_get_drvdata(pdev); - if (!adata) { - if (np) - of_node_put(np); - return; - } + struct regmap *anatop; #define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0 #define HW_ANADIG_USB2_CHRG_DETECT 0x00000210 @@ -141,20 +129,21 @@ static void __init imx6q_usb_init(void) #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000 - /* - * The external charger detector needs to be disabled, - * or the signal at DP will be poor - */ - anatop_write_reg(adata, HW_ANADIG_USB1_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B - | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B, - ~0); - anatop_write_reg(adata, HW_ANADIG_USB2_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B | - BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B, - ~0); - - of_node_put(np); + anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); + if (!IS_ERR(anatop)) { + /* + * The external charger detector needs to be disabled, + * or the signal at DP will be poor + */ + regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B + | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); + regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B | + BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); + } else { + pr_warn("failed to find fsl,imx6q-anatop regmap\n"); + } } static void __init imx6q_init_machine(void) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4e932cc695e9..2ae1d97fac1e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -112,7 +112,7 @@ config REGULATOR_DA9052 config REGULATOR_ANATOP tristate "Freescale i.MX on-chip ANATOP LDO regulators" - depends on MFD_ANATOP + depends on MFD_SYSCON help Say y here to support Freescale i.MX on-chip ANATOP LDOs regulators. It is recommended that this option be diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index e9c2085f9dfb..596535dd917a 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c @@ -21,19 +21,20 @@ #include #include #include +#include #include #include #include #include #include -#include +#include #include #include struct anatop_regulator { const char *name; u32 control_reg; - struct anatop *mfd; + struct regmap *anatop; int vol_bit_shift; int vol_bit_width; int min_bit_val; @@ -43,7 +44,8 @@ struct anatop_regulator { struct regulator_init_data *initdata; }; -static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) +static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg, + unsigned selector) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); u32 val, mask; @@ -56,12 +58,13 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) mask = ((1 << anatop_reg->vol_bit_width) - 1) << anatop_reg->vol_bit_shift; val <<= anatop_reg->vol_bit_shift; - anatop_write_reg(anatop_reg->mfd, anatop_reg->control_reg, val, mask); + regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg, + mask, val); return 0; } -static int anatop_get_voltage_sel(struct regulator_dev *reg) +static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg) { struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); u32 val; @@ -69,7 +72,7 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg) if (!anatop_reg->control_reg) return -ENOTSUPP; - val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); + regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val); val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >> anatop_reg->vol_bit_shift; @@ -77,8 +80,8 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg) } static struct regulator_ops anatop_rops = { - .set_voltage_sel = anatop_set_voltage_sel, - .get_voltage_sel = anatop_get_voltage_sel, + .set_voltage_sel = anatop_regmap_set_voltage_sel, + .get_voltage_sel = anatop_regmap_get_voltage_sel, .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, }; @@ -87,11 +90,11 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; + struct device_node *anatop_np; struct regulator_desc *rdesc; struct regulator_dev *rdev; struct anatop_regulator *sreg; struct regulator_init_data *initdata; - struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; int ret = 0; @@ -108,7 +111,15 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev) rdesc->ops = &anatop_rops; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; - sreg->mfd = anatopmfd; + + anatop_np = of_get_parent(np); + if (!anatop_np) + return -ENODEV; + sreg->anatop = syscon_node_to_regmap(anatop_np); + of_node_put(anatop_np); + if (IS_ERR(sreg->anatop)) + return PTR_ERR(sreg->anatop); + ret = of_property_read_u32(np, "anatop-reg-offset", &sreg->control_reg); if (ret) { -- cgit v1.2.3 From 51acdb61185e9c7579366712a415fc929929d3bb Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 17 Sep 2012 12:19:05 +0800 Subject: mfd: max8925: Remove array in regulator platform data Remove array in parent's platform data. Use struct regulator_init_data as regulator device's platform data directly. So a lot of pdata are added into parent's platform data. And voltage out register offset is used as IORESOURCE_REG to distinguish different regualtor devices. Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/max8925-core.c | 388 +++++++++++++++++++++++++++------- drivers/regulator/max8925-regulator.c | 35 ++- include/linux/mfd/max8925.h | 26 ++- 3 files changed, 356 insertions(+), 93 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 934be40cd542..9f54c04912f2 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -109,71 +110,215 @@ static struct mfd_cell onkey_devs[] = { }, }; -#define MAX8925_REG_RESOURCE(_start, _end) \ -{ \ - .start = MAX8925_##_start, \ - .end = MAX8925_##_end, \ - .flags = IORESOURCE_REG, \ -} +static struct resource sd1_resources[] __devinitdata = { + {0x06, 0x06, "sdv", IORESOURCE_REG, }, +}; -static struct resource regulator_resources[] = { - MAX8925_REG_RESOURCE(SDCTL1, SDCTL1), - MAX8925_REG_RESOURCE(SDCTL2, SDCTL2), - MAX8925_REG_RESOURCE(SDCTL3, SDCTL3), - MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1), - MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2), - MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3), - MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4), - MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5), - MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6), - MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7), - MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8), - MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9), - MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10), - MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11), - MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12), - MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13), - MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14), - MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15), - MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16), - MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17), - MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18), - MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19), - MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20), -}; - -#define MAX8925_REG_DEVS(_id) \ -{ \ - .name = "max8925-regulator", \ - .num_resources = 1, \ - .resources = ®ulator_resources[MAX8925_ID_##_id], \ - .id = MAX8925_ID_##_id, \ -} +static struct resource sd2_resources[] __devinitdata = { + {0x09, 0x09, "sdv", IORESOURCE_REG, }, +}; + +static struct resource sd3_resources[] __devinitdata = { + {0x0c, 0x0c, "sdv", IORESOURCE_REG, }, +}; + +static struct resource ldo1_resources[] __devinitdata = { + {0x1a, 0x1a, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo2_resources[] __devinitdata = { + {0x1e, 0x1e, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo3_resources[] __devinitdata = { + {0x22, 0x22, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo4_resources[] __devinitdata = { + {0x26, 0x26, "ldov", IORESOURCE_REG, }, +}; -static struct mfd_cell regulator_devs[] = { - MAX8925_REG_DEVS(SD1), - MAX8925_REG_DEVS(SD2), - MAX8925_REG_DEVS(SD3), - MAX8925_REG_DEVS(LDO1), - MAX8925_REG_DEVS(LDO2), - MAX8925_REG_DEVS(LDO3), - MAX8925_REG_DEVS(LDO4), - MAX8925_REG_DEVS(LDO5), - MAX8925_REG_DEVS(LDO6), - MAX8925_REG_DEVS(LDO7), - MAX8925_REG_DEVS(LDO8), - MAX8925_REG_DEVS(LDO9), - MAX8925_REG_DEVS(LDO10), - MAX8925_REG_DEVS(LDO11), - MAX8925_REG_DEVS(LDO12), - MAX8925_REG_DEVS(LDO13), - MAX8925_REG_DEVS(LDO14), - MAX8925_REG_DEVS(LDO15), - MAX8925_REG_DEVS(LDO16), - MAX8925_REG_DEVS(LDO17), - MAX8925_REG_DEVS(LDO18), - MAX8925_REG_DEVS(LDO19), - MAX8925_REG_DEVS(LDO20), +static struct resource ldo5_resources[] __devinitdata = { + {0x2a, 0x2a, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo6_resources[] __devinitdata = { + {0x2e, 0x2e, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo7_resources[] __devinitdata = { + {0x32, 0x32, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo8_resources[] __devinitdata = { + {0x36, 0x36, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo9_resources[] __devinitdata = { + {0x3a, 0x3a, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo10_resources[] __devinitdata = { + {0x3e, 0x3e, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo11_resources[] __devinitdata = { + {0x42, 0x42, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo12_resources[] __devinitdata = { + {0x46, 0x46, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo13_resources[] __devinitdata = { + {0x4a, 0x4a, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo14_resources[] __devinitdata = { + {0x4e, 0x4e, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo15_resources[] __devinitdata = { + {0x52, 0x52, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo16_resources[] __devinitdata = { + {0x12, 0x12, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo17_resources[] __devinitdata = { + {0x16, 0x16, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo18_resources[] __devinitdata = { + {0x74, 0x74, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo19_resources[] __devinitdata = { + {0x5e, 0x5e, "ldov", IORESOURCE_REG, }, +}; + +static struct resource ldo20_resources[] __devinitdata = { + {0x9e, 0x9e, "ldov", IORESOURCE_REG, }, +}; + +static struct mfd_cell reg_devs[] __devinitdata = { + { + .name = "max8925-regulator", + .id = 0, + .num_resources = ARRAY_SIZE(sd1_resources), + .resources = sd1_resources, + }, { + .name = "max8925-regulator", + .id = 1, + .num_resources = ARRAY_SIZE(sd2_resources), + .resources = sd2_resources, + }, { + .name = "max8925-regulator", + .id = 2, + .num_resources = ARRAY_SIZE(sd3_resources), + .resources = sd3_resources, + }, { + .name = "max8925-regulator", + .id = 3, + .num_resources = ARRAY_SIZE(ldo1_resources), + .resources = ldo1_resources, + }, { + .name = "max8925-regulator", + .id = 4, + .num_resources = ARRAY_SIZE(ldo2_resources), + .resources = ldo2_resources, + }, { + .name = "max8925-regulator", + .id = 5, + .num_resources = ARRAY_SIZE(ldo3_resources), + .resources = ldo3_resources, + }, { + .name = "max8925-regulator", + .id = 6, + .num_resources = ARRAY_SIZE(ldo4_resources), + .resources = ldo4_resources, + }, { + .name = "max8925-regulator", + .id = 7, + .num_resources = ARRAY_SIZE(ldo5_resources), + .resources = ldo5_resources, + }, { + .name = "max8925-regulator", + .id = 8, + .num_resources = ARRAY_SIZE(ldo6_resources), + .resources = ldo6_resources, + }, { + .name = "max8925-regulator", + .id = 9, + .num_resources = ARRAY_SIZE(ldo7_resources), + .resources = ldo7_resources, + }, { + .name = "max8925-regulator", + .id = 10, + .num_resources = ARRAY_SIZE(ldo8_resources), + .resources = ldo8_resources, + }, { + .name = "max8925-regulator", + .id = 11, + .num_resources = ARRAY_SIZE(ldo9_resources), + .resources = ldo9_resources, + }, { + .name = "max8925-regulator", + .id = 12, + .num_resources = ARRAY_SIZE(ldo10_resources), + .resources = ldo10_resources, + }, { + .name = "max8925-regulator", + .id = 13, + .num_resources = ARRAY_SIZE(ldo11_resources), + .resources = ldo11_resources, + }, { + .name = "max8925-regulator", + .id = 14, + .num_resources = ARRAY_SIZE(ldo12_resources), + .resources = ldo12_resources, + }, { + .name = "max8925-regulator", + .id = 15, + .num_resources = ARRAY_SIZE(ldo13_resources), + .resources = ldo13_resources, + }, { + .name = "max8925-regulator", + .id = 16, + .num_resources = ARRAY_SIZE(ldo14_resources), + .resources = ldo14_resources, + }, { + .name = "max8925-regulator", + .id = 17, + .num_resources = ARRAY_SIZE(ldo15_resources), + .resources = ldo15_resources, + }, { + .name = "max8925-regulator", + .id = 18, + .num_resources = ARRAY_SIZE(ldo16_resources), + .resources = ldo16_resources, + }, { + .name = "max8925-regulator", + .id = 19, + .num_resources = ARRAY_SIZE(ldo17_resources), + .resources = ldo17_resources, + }, { + .name = "max8925-regulator", + .id = 20, + .num_resources = ARRAY_SIZE(ldo18_resources), + .resources = ldo18_resources, + }, { + .name = "max8925-regulator", + .id = 21, + .num_resources = ARRAY_SIZE(ldo19_resources), + .resources = ldo19_resources, + }, { + .name = "max8925-regulator", + .id = 22, + .num_resources = ARRAY_SIZE(ldo20_resources), + .resources = ldo20_resources, + }, }; enum { @@ -569,6 +714,113 @@ tsc_irq: return 0; } +static void __devinit init_regulator(struct max8925_chip *chip, + struct max8925_platform_data *pdata) +{ + int ret; + + if (!pdata) + return; + if (pdata->sd1) { + reg_devs[0].platform_data = pdata->sd1; + reg_devs[0].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->sd2) { + reg_devs[1].platform_data = pdata->sd2; + reg_devs[1].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->sd3) { + reg_devs[2].platform_data = pdata->sd3; + reg_devs[2].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo1) { + reg_devs[3].platform_data = pdata->ldo1; + reg_devs[3].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo2) { + reg_devs[4].platform_data = pdata->ldo2; + reg_devs[4].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo3) { + reg_devs[5].platform_data = pdata->ldo3; + reg_devs[5].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo4) { + reg_devs[6].platform_data = pdata->ldo4; + reg_devs[6].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo5) { + reg_devs[7].platform_data = pdata->ldo5; + reg_devs[7].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo6) { + reg_devs[8].platform_data = pdata->ldo6; + reg_devs[8].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo7) { + reg_devs[9].platform_data = pdata->ldo7; + reg_devs[9].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo8) { + reg_devs[10].platform_data = pdata->ldo8; + reg_devs[10].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo9) { + reg_devs[11].platform_data = pdata->ldo9; + reg_devs[11].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo10) { + reg_devs[12].platform_data = pdata->ldo10; + reg_devs[12].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo11) { + reg_devs[13].platform_data = pdata->ldo11; + reg_devs[13].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo12) { + reg_devs[14].platform_data = pdata->ldo12; + reg_devs[14].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo13) { + reg_devs[15].platform_data = pdata->ldo13; + reg_devs[15].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo14) { + reg_devs[16].platform_data = pdata->ldo14; + reg_devs[16].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo15) { + reg_devs[17].platform_data = pdata->ldo15; + reg_devs[17].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo16) { + reg_devs[18].platform_data = pdata->ldo16; + reg_devs[18].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo17) { + reg_devs[19].platform_data = pdata->ldo17; + reg_devs[19].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo18) { + reg_devs[20].platform_data = pdata->ldo18; + reg_devs[20].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo19) { + reg_devs[21].platform_data = pdata->ldo19; + reg_devs[21].pdata_size = sizeof(struct regulator_init_data); + } + if (pdata->ldo20) { + reg_devs[22].platform_data = pdata->ldo20; + reg_devs[22].pdata_size = sizeof(struct regulator_init_data); + } + ret = mfd_add_devices(chip->dev, 0, reg_devs, ARRAY_SIZE(reg_devs), + NULL, 0, NULL); + if (ret < 0) { + dev_err(chip->dev, "Failed to add regulator subdev\n"); + return; + } +} + int __devinit max8925_device_init(struct max8925_chip *chip, struct max8925_platform_data *pdata) { @@ -608,15 +860,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, goto out_dev; } - if (pdata) { - ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], - ARRAY_SIZE(regulator_devs), - ®ulator_resources[0], 0, NULL); - if (ret < 0) { - dev_err(chip->dev, "Failed to add regulator subdev\n"); - goto out_dev; - } - } + init_regulator(chip, pdata); if (pdata && pdata->backlight) { bk_devs[0].platform_data = &pdata->backlight; diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c index 43dc97ec3932..9bb0be37495f 100644 --- a/drivers/regulator/max8925-regulator.c +++ b/drivers/regulator/max8925-regulator.c @@ -214,37 +214,36 @@ static struct max8925_regulator_info max8925_regulator_info[] = { MAX8925_LDO(20, 750, 3900, 50), }; -static struct max8925_regulator_info * __devinit find_regulator_info(int id) -{ - struct max8925_regulator_info *ri; - int i; - - for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { - ri = &max8925_regulator_info[i]; - if (ri->desc.id == id) - return ri; - } - return NULL; -} - static int __devinit max8925_regulator_probe(struct platform_device *pdev) { struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct max8925_platform_data *pdata = chip->dev->platform_data; + struct regulator_init_data *pdata = pdev->dev.platform_data; struct regulator_config config = { }; struct max8925_regulator_info *ri; + struct resource *res; struct regulator_dev *rdev; + int i; - ri = find_regulator_info(pdev->id); - if (ri == NULL) { - dev_err(&pdev->dev, "invalid regulator ID specified\n"); + res = platform_get_resource(pdev, IORESOURCE_REG, 0); + if (!res) { + dev_err(&pdev->dev, "No REG resource!\n"); + return -EINVAL; + } + for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) { + ri = &max8925_regulator_info[i]; + if (ri->vol_reg == res->start) + break; + } + if (i == ARRAY_SIZE(max8925_regulator_info)) { + dev_err(&pdev->dev, "Failed to find regulator %llu\n", + (unsigned long long)res->start); return -EINVAL; } ri->i2c = chip->i2c; ri->chip = chip; config.dev = &pdev->dev; - config.init_data = pdata->regulator[pdev->id]; + config.init_data = pdata; config.driver_data = ri; rdev = regulator_register(&ri->desc, &config); diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h index 15b2392a56fb..74d8e2969630 100644 --- a/include/linux/mfd/max8925.h +++ b/include/linux/mfd/max8925.h @@ -158,8 +158,6 @@ enum { #define TSC_IRQ_MASK (0x03) #define RTC_IRQ_MASK (0x0c) -#define MAX8925_MAX_REGULATOR (23) - #define MAX8925_NAME_SIZE (32) /* IRQ definitions */ @@ -236,7 +234,29 @@ struct max8925_platform_data { struct max8925_backlight_pdata *backlight; struct max8925_touch_pdata *touch; struct max8925_power_pdata *power; - struct regulator_init_data *regulator[MAX8925_MAX_REGULATOR]; + struct regulator_init_data *sd1; + struct regulator_init_data *sd2; + struct regulator_init_data *sd3; + struct regulator_init_data *ldo1; + struct regulator_init_data *ldo2; + struct regulator_init_data *ldo3; + struct regulator_init_data *ldo4; + struct regulator_init_data *ldo5; + struct regulator_init_data *ldo6; + struct regulator_init_data *ldo7; + struct regulator_init_data *ldo8; + struct regulator_init_data *ldo9; + struct regulator_init_data *ldo10; + struct regulator_init_data *ldo11; + struct regulator_init_data *ldo12; + struct regulator_init_data *ldo13; + struct regulator_init_data *ldo14; + struct regulator_init_data *ldo15; + struct regulator_init_data *ldo16; + struct regulator_init_data *ldo17; + struct regulator_init_data *ldo18; + struct regulator_init_data *ldo19; + struct regulator_init_data *ldo20; int irq_base; int tsc_irq; -- cgit v1.2.3 From e7a7810ae08bfca5cb2cad8a8d55c16f299cc3fe Mon Sep 17 00:00:00 2001 From: "Jett.Zhou" Date: Mon, 17 Sep 2012 12:19:06 +0800 Subject: regulator: 88pm860x: Add pre-regulator support for 88pm860x regulator Pre-regulator of 88pm8606 is mainly for support charging based on vbus, it needs to be enabled for charging battery, and will be disabled in some exception condition like over-temp. Add the pre-regulator support for 88pm860x regulator driver. Signed-off-by: Jett.Zhou Acked-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/regulator/88pm8607.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index 843c89a15472..d34bd8c5ad08 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -23,6 +23,7 @@ struct pm8607_regulator_info { struct pm860x_chip *chip; struct regulator_dev *regulator; struct i2c_client *i2c; + struct i2c_client *i2c_8606; unsigned int *vol_table; unsigned int *vol_suspend; @@ -242,6 +243,35 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) return ret; } +static int pm8606_preg_enable(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + + return pm860x_set_bits(info->i2c, rdev->desc->enable_reg, + 1 << rdev->desc->enable_mask, 0); +} + +static int pm8606_preg_disable(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + + return pm860x_set_bits(info->i2c, rdev->desc->enable_reg, + 1 << rdev->desc->enable_mask, + 1 << rdev->desc->enable_mask); +} + +static int pm8606_preg_is_enabled(struct regulator_dev *rdev) +{ + struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); + int ret; + + ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg); + if (ret < 0) + return ret; + + return !((unsigned char)ret & (1 << rdev->desc->enable_mask)); +} + static struct regulator_ops pm8607_regulator_ops = { .list_voltage = pm8607_list_voltage, .set_voltage_sel = pm8607_set_voltage_sel, @@ -251,6 +281,25 @@ static struct regulator_ops pm8607_regulator_ops = { .is_enabled = regulator_is_enabled_regmap, }; +static struct regulator_ops pm8606_preg_ops = { + .enable = pm8606_preg_enable, + .disable = pm8606_preg_disable, + .is_enabled = pm8606_preg_is_enabled, +}; + +#define PM8606_PREG(ereg, ebit) \ +{ \ + .desc = { \ + .name = "PREG", \ + .ops = &pm8606_preg_ops, \ + .type = REGULATOR_CURRENT, \ + .id = PM8606_ID_PREG, \ + .owner = THIS_MODULE, \ + .enable_reg = PM8606_##ereg, \ + .enable_mask = (ebit), \ + }, \ +} + #define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \ { \ .desc = { \ @@ -309,6 +358,8 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = { PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5), PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0), PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6), + + PM8606_PREG(PREREGULATORB, 5), }; static int __devinit pm8607_regulator_probe(struct platform_device *pdev) @@ -336,6 +387,8 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) return -EINVAL; } info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; + info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : + chip->client; info->chip = chip; /* check DVC ramp slope double */ @@ -371,6 +424,18 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev) return 0; } +static struct platform_device_id pm8607_regulator_driver_ids[] = { + { + .name = "88pm860x-regulator", + .driver_data = 0, + }, { + .name = "88pm860x-preg", + .driver_data = 0, + }, + { }, +}; +MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids); + static struct platform_driver pm8607_regulator_driver = { .driver = { .name = "88pm860x-regulator", @@ -378,6 +443,7 @@ static struct platform_driver pm8607_regulator_driver = { }, .probe = pm8607_regulator_probe, .remove = __devexit_p(pm8607_regulator_remove), + .id_table = pm8607_regulator_driver_ids, }; static int __init pm8607_regulator_init(void) -- cgit v1.2.3 From ff13e9e256d49a478b34da3dc380af41e0b9175f Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 17 Sep 2012 12:19:07 +0800 Subject: mfd: 88pm860x: Avoid to check resource for preg regulator Since PREG regulator is the only one regulator in 88PM8606, and other regulators are in 88PM8607. Checking resource as identifying regulator is not a good way. We can use NULL resource to indentify PREG regulator. Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-core.c | 8 +------- drivers/regulator/88pm8607.c | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index ad966c413087..8bf7622300f4 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -150,10 +150,6 @@ static struct resource charger_resources[] __devinitdata = { {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, }; -static struct resource preg_resources[] __devinitdata = { - {PM8606_ID_PREG, PM8606_ID_PREG, "preg", IORESOURCE_REG,}, -}; - static struct resource rtc_resources[] __devinitdata = { {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,}, }; @@ -960,10 +956,8 @@ static void __devinit device_power_init(struct pm860x_chip *chip, power_devs[2].platform_data = &preg_init_data; power_devs[2].pdata_size = sizeof(struct regulator_init_data); - power_devs[2].num_resources = ARRAY_SIZE(preg_resources); - power_devs[2].resources = &preg_resources[0], ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, - &preg_resources[0], chip->irq_base, NULL); + NULL, chip->irq_base, NULL); if (ret < 0) dev_err(chip->dev, "Failed to add preg subdev\n"); } diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index d34bd8c5ad08..f96fbe38ff6f 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -358,7 +358,9 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = { PM8607_LDO(12, LDO12, 0, SUPPLIES_EN12, 5), PM8607_LDO(13, VIBRATOR_SET, 1, VIBRATOR_SET, 0), PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6), +}; +static struct pm8607_regulator_info pm8606_regulator_info[] = { PM8606_PREG(PREREGULATORB, 5), }; @@ -372,19 +374,23 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) int i; res = platform_get_resource(pdev, IORESOURCE_REG, 0); - if (res == NULL) { - dev_err(&pdev->dev, "No REG resource!\n"); - return -EINVAL; - } - for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { - info = &pm8607_regulator_info[i]; - if (info->desc.vsel_reg == res->start) - break; - } - if (i == ARRAY_SIZE(pm8607_regulator_info)) { - dev_err(&pdev->dev, "Failed to find regulator %llu\n", - (unsigned long long)res->start); - return -EINVAL; + if (res) { + /* There're resources in 88PM8607 regulator driver */ + for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { + info = &pm8607_regulator_info[i]; + if (info->desc.vsel_reg == res->start) + break; + } + if (i == ARRAY_SIZE(pm8607_regulator_info)) { + dev_err(&pdev->dev, "Failed to find regulator %llu\n", + (unsigned long long)res->start); + return -EINVAL; + } + } else { + /* There's no resource in 88PM8606 PREG regulator driver */ + info = &pm8606_regulator_info[0]; + /* i is used to check regulator ID */ + i = -1; } info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion : -- cgit v1.2.3 From a361cd9f2e9f2110e03ebeb6c4fb000a9a1adf2d Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Tue, 28 Aug 2012 13:47:40 +0200 Subject: regulator: palmas: Add DT support Add DT support to palmas regulator. This involved a little change to the platform data structure. Regulator information can now come from platform data or DT. Signed-off-by: Graeme Gregory Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Samuel Ortiz --- drivers/regulator/palmas-regulator.c | 127 ++++++++++++++++++++++++++++++++--- 1 file changed, 119 insertions(+), 8 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 17d19fbbc490..a8294e5bcf36 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include struct regs_info { char *name; @@ -603,10 +606,103 @@ static int palmas_ldo_init(struct palmas *palmas, int id, return 0; } +static struct of_regulator_match palmas_matches[] = { + { .name = "smps12", }, + { .name = "smps123", }, + { .name = "smps3", }, + { .name = "smps45", }, + { .name = "smps457", }, + { .name = "smps6", }, + { .name = "smps7", }, + { .name = "smps8", }, + { .name = "smps9", }, + { .name = "smps10", }, + { .name = "ldo1", }, + { .name = "ldo2", }, + { .name = "ldo3", }, + { .name = "ldo4", }, + { .name = "ldo5", }, + { .name = "ldo6", }, + { .name = "ldo7", }, + { .name = "ldo8", }, + { .name = "ldo9", }, + { .name = "ldoln", }, + { .name = "ldousb", }, +}; + +static void __devinit palmas_dt_to_pdata(struct device *dev, + struct device_node *node, + struct palmas_pmic_platform_data *pdata) +{ + struct device_node *regulators; + u32 prop; + int idx, ret; + + regulators = of_find_node_by_name(node, "regulators"); + if (!regulators) { + dev_info(dev, "regulator node not found\n"); + return; + } + + ret = of_regulator_match(dev, regulators, palmas_matches, + PALMAS_NUM_REGS); + if (ret < 0) { + dev_err(dev, "Error parsing regulator init data: %d\n", ret); + return; + } + + for (idx = 0; idx < PALMAS_NUM_REGS; idx++) { + if (!palmas_matches[idx].init_data || + !palmas_matches[idx].of_node) + continue; + + pdata->reg_data[idx] = palmas_matches[idx].init_data; + + pdata->reg_init[idx] = devm_kzalloc(dev, + sizeof(struct palmas_reg_init), GFP_KERNEL); + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,warm_reset", &prop); + if (!ret) + pdata->reg_init[idx]->warm_reset = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,roof_floor", &prop); + if (!ret) + pdata->reg_init[idx]->roof_floor = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,mode_sleep", &prop); + if (!ret) + pdata->reg_init[idx]->mode_sleep = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,warm_reset", &prop); + if (!ret) + pdata->reg_init[idx]->warm_reset = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,tstep", &prop); + if (!ret) + pdata->reg_init[idx]->tstep = prop; + + ret = of_property_read_u32(palmas_matches[idx].of_node, + "ti,vsel", &prop); + if (!ret) + pdata->reg_init[idx]->vsel = prop; + } + + ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop); + if (!ret) + pdata->ldo6_vibrator = prop; +} + + static __devinit int palmas_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; + struct device_node *node = pdev->dev.of_node; struct regulator_dev *rdev; struct regulator_config config = { }; struct palmas_pmic *pmic; @@ -614,10 +710,14 @@ static __devinit int palmas_probe(struct platform_device *pdev) int id = 0, ret; unsigned int addr, reg; - if (!pdata) - return -EINVAL; - if (!pdata->reg_data) - return -EINVAL; + if (node && !pdata) { + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + + if (!pdata) + return -ENOMEM; + + palmas_dt_to_pdata(&pdev->dev, node, pdata); + } pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) @@ -694,7 +794,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].owner = THIS_MODULE; /* Initialise sleep/init values from platform data */ - if (pdata && pdata->reg_init) { + if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { ret = palmas_smps_init(palmas, id, reg_init); @@ -718,11 +818,13 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->range[id] = 1; } - if (pdata && pdata->reg_data) + if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; + config.of_node = palmas_matches[id].of_node; + rdev = regulator_register(&pmic->desc[id], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, @@ -756,11 +858,13 @@ static __devinit int palmas_probe(struct platform_device *pdev) palmas_regs_info[id].ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; - if (pdata && pdata->reg_data) + if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; + config.of_node = palmas_matches[id].of_node; + rdev = regulator_register(&pmic->desc[id], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, @@ -774,7 +878,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->rdev[id] = rdev; /* Initialise sleep/init values from platform data */ - if (pdata->reg_init) { + if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { ret = palmas_ldo_init(palmas, id, reg_init); @@ -802,9 +906,15 @@ static int __devexit palmas_remove(struct platform_device *pdev) return 0; } +static struct of_device_id __devinitdata of_palmas_match_tbl[] = { + { .compatible = "ti,palmas-pmic", }, + { /* end */ } +}; + static struct platform_driver palmas_driver = { .driver = { .name = "palmas-pmic", + .of_match_table = of_palmas_match_tbl, .owner = THIS_MODULE, }, .probe = palmas_probe, @@ -827,3 +937,4 @@ MODULE_AUTHOR("Graeme Gregory "); MODULE_DESCRIPTION("Palmas voltage regulator driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:palmas-pmic"); +MODULE_DEVICE_TABLE(of, of_palmas_match_tbl); -- cgit v1.2.3 From 2e57d56747e601b3e0ff6697e524025d0504d161 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Fri, 21 Sep 2012 18:06:52 +0800 Subject: mfd: 88pm860x: Device tree support Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- Documentation/devicetree/bindings/mfd/88pm860x.txt | 85 ++++++++++++++++++++++ .../devicetree/bindings/regulator/88pm860x.txt | 30 ++++++++ .../bindings/video/backlight/88pm860x.txt | 15 ++++ drivers/input/touchscreen/88pm860x-ts.c | 46 ++++++++---- drivers/leds/leds-88pm860x.c | 33 ++++++++- drivers/mfd/88pm860x-core.c | 62 +++++++++++++--- drivers/regulator/88pm8607.c | 35 ++++++++- drivers/rtc/rtc-88pm860x.c | 43 ++++++++--- drivers/video/backlight/88pm860x_bl.c | 39 +++++++++- include/linux/mfd/88pm860x.h | 4 +- 10 files changed, 351 insertions(+), 41 deletions(-) create mode 100644 Documentation/devicetree/bindings/mfd/88pm860x.txt create mode 100644 Documentation/devicetree/bindings/regulator/88pm860x.txt create mode 100644 Documentation/devicetree/bindings/video/backlight/88pm860x.txt (limited to 'drivers/regulator') diff --git a/Documentation/devicetree/bindings/mfd/88pm860x.txt b/Documentation/devicetree/bindings/mfd/88pm860x.txt new file mode 100644 index 000000000000..63f3ee33759c --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/88pm860x.txt @@ -0,0 +1,85 @@ +* Marvell 88PM860x Power Management IC + +Required parent device properties: +- compatible : "marvell,88pm860x" +- reg : the I2C slave address for the 88pm860x chip +- interrupts : IRQ line for the 88pm860x chip +- interrupt-controller: describes the 88pm860x as an interrupt controller (has its own domain) +- #interrupt-cells : should be 1. + - The cell is the 88pm860x local IRQ number + +Optional parent device properties: +- marvell,88pm860x-irq-read-clr: inicates whether interrupt status is cleared by read +- marvell,88pm860x-slave-addr: 88pm860x are two chips solution. stores the I2C address + of one chip, and this property stores the I2C address of + another chip. + +88pm860x consists of a large and varied group of sub-devices: + +Device Supply Names Description +------ ------------ ----------- +88pm860x-onkey : : On key +88pm860x-rtc : : RTC +88pm8607 : : Regulators +88pm860x-backlight : : Backlight +88pm860x-led : : Led +88pm860x-touch : : Touchscreen + +Example: + + pmic: 88pm860x@34 { + compatible = "marvell,88pm860x"; + reg = <0x34>; + interrupts = <4>; + interrupt-parent = <&intc>; + interrupt-controller; + #interrupt-cells = <1>; + + marvell,88pm860x-irq-read-clr; + marvell,88pm860x-slave-addr = <0x11>; + + regulators { + BUCK1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + LDO1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <2800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + rtc { + marvell,88pm860x-vrtc = <1>; + }; + touch { + marvell,88pm860x-gpadc-prebias = <1>; + marvell,88pm860x-gpadc-slot-cycle = <1>; + marvell,88pm860x-tsi-prebias = <6>; + marvell,88pm860x-pen-prebias = <16>; + marvell,88pm860x-pen-prechg = <2>; + marvell,88pm860x-resistor-X = <300>; + }; + backlights { + backlight-0 { + marvell,88pm860x-iset = <4>; + marvell,88pm860x-pwm = <3>; + }; + backlight-2 { + }; + }; + leds { + led0-red { + marvell,88pm860x-iset = <12>; + }; + led0-green { + marvell,88pm860x-iset = <12>; + }; + led0-blue { + marvell,88pm860x-iset = <12>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/regulator/88pm860x.txt b/Documentation/devicetree/bindings/regulator/88pm860x.txt new file mode 100644 index 000000000000..1267b3e1a2cc --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/88pm860x.txt @@ -0,0 +1,30 @@ +Marvell 88PM860x regulator + +Required properties: +- compatible: "marvell,88pm860x" +- reg: I2C slave address +- regulators: A node that houses a sub-node for each regulator within the + device. Each sub-node is identified using the regulator-compatible + property, with valid values listed below. + +Example: + + pmic: 88pm860x@34 { + compatible = "marvell,88pm860x"; + reg = <0x34>; + + regulators { + BUCK1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + BUCK3 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/video/backlight/88pm860x.txt b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt new file mode 100644 index 000000000000..261df2799315 --- /dev/null +++ b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt @@ -0,0 +1,15 @@ +88pm860x-backlight bindings + +Optional properties: + - marvell,88pm860x-iset: Current supplies on backlight device. + - marvell,88pm860x-pwm: PWM frequency on backlight device. + +Example: + + backlights { + backlight-0 { + marvell,88pm860x-iset = <4>; + marvell,88pm860x-pwm = <3>; + }; + backlight-2 { + }; diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 05f30b73c3c3..4f81e6eb74b6 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include @@ -113,14 +114,31 @@ static void pm860x_touch_close(struct input_dev *dev) pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); } +#ifdef CONFIG_OF +static int __devinit pm860x_touch_dt_init(struct platform_device *pdev, + int *res_x) +{ + struct device_node *np = pdev->dev.parent->of_node; + if (!np) + return -ENODEV; + np = of_find_node_by_name(np, "touch"); + if (!np) { + dev_err(&pdev->dev, "Can't find touch node\n"); + return -EINVAL; + } + of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x); + return 0; +} +#else +#define pm860x_touch_dt_init(x, y) (-1) +#endif + static int __devinit pm860x_touch_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct pm860x_platform_data *pm860x_pdata = \ - pdev->dev.parent->platform_data; - struct pm860x_touch_pdata *pdata = NULL; + struct pm860x_touch_pdata *pdata = pdev->dev.platform_data; struct pm860x_touch *touch; - int irq, ret; + int irq, ret, res_x = 0; irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -128,15 +146,13 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) return -EINVAL; } - if (!pm860x_pdata) { - dev_err(&pdev->dev, "platform data is missing\n"); - return -EINVAL; - } - - pdata = pm860x_pdata->touch; - if (!pdata) { - dev_err(&pdev->dev, "touchscreen data is missing\n"); - return -EINVAL; + if (pm860x_touch_dt_init(pdev, &res_x)) { + if (pdata) + res_x = pdata->res_x; + else { + dev_err(&pdev->dev, "failed to get platform data\n"); + return -EINVAL; + } } touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); @@ -159,8 +175,8 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) touch->idev->close = pm860x_touch_close; touch->chip = chip; touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; - touch->irq = irq + chip->irq_base; - touch->res_x = pdata->res_x; + touch->irq = irq; + touch->res_x = res_x; input_set_drvdata(touch->idev, touch); ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c index 70232b1756f9..b7e8cc0957fc 100644 --- a/drivers/leds/leds-88pm860x.c +++ b/drivers/leds/leds-88pm860x.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -123,6 +124,33 @@ static void pm860x_led_set(struct led_classdev *cdev, schedule_work(&data->work); } +#ifdef CONFIG_OF +static int pm860x_led_dt_init(struct platform_device *pdev, + struct pm860x_led *data) +{ + struct device_node *nproot = pdev->dev.parent->of_node, *np; + int iset = 0; + if (!nproot) + return -ENODEV; + nproot = of_find_node_by_name(nproot, "leds"); + if (!nproot) { + dev_err(&pdev->dev, "failed to find leds node\n"); + return -ENODEV; + } + for_each_child_of_node(nproot, np) { + if (!of_node_cmp(np->name, data->name)) { + of_property_read_u32(np, "marvell,88pm860x-iset", + &iset); + data->iset = PM8606_LED_CURRENT(iset); + break; + } + } + return 0; +} +#else +#define pm860x_led_dt_init(x, y) (-1) +#endif + static int pm860x_led_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -179,8 +207,9 @@ static int pm860x_led_probe(struct platform_device *pdev) data->chip = chip; data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; data->port = pdev->id; - if (pdata && pdata->iset) - data->iset = pdata->iset; + if (pm860x_led_dt_init(pdev, data)) + if (pdata) + data->iset = pdata->iset; data->current_brightness = 0; data->cdev.name = data->name; diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 5b56fe8250b4..fdaf6861ce95 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -1112,12 +1114,6 @@ static void __devexit pm860x_device_exit(struct pm860x_chip *chip) mfd_remove_devices(chip->dev); } -static const struct i2c_device_id pm860x_id_table[] = { - { "88PM860x", 0 }, - {} -}; -MODULE_DEVICE_TABLE(i2c, pm860x_id_table); - static int verify_addr(struct i2c_client *i2c) { unsigned short addr_8607[] = {0x30, 0x34}; @@ -1144,21 +1140,52 @@ static struct regmap_config pm860x_regmap_config = { .val_bits = 8, }; +static int __devinit pm860x_dt_init(struct device_node *np, + struct device *dev, + struct pm860x_platform_data *pdata) +{ + int ret; + + if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL)) + pdata->irq_mode = 1; + ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr", + &pdata->companion_addr); + if (ret) { + dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" " + "property\n"); + pdata->companion_addr = 0; + } + return 0; +} + static int __devinit pm860x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pm860x_platform_data *pdata = client->dev.platform_data; + struct device_node *node = client->dev.of_node; struct pm860x_chip *chip; int ret; - if (!pdata) { + if (node && !pdata) { + /* parse DT to get platform data */ + pdata = devm_kzalloc(&client->dev, + sizeof(struct pm860x_platform_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + ret = pm860x_dt_init(node, &client->dev, pdata); + if (ret) + goto err; + } else if (!pdata) { pr_info("No platform data in %s!\n", __func__); return -EINVAL; } chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; + if (chip == NULL) { + ret = -ENOMEM; + goto err; + } chip->id = verify_addr(client); chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); @@ -1198,6 +1225,10 @@ static int __devinit pm860x_probe(struct i2c_client *client, pm860x_device_init(chip, pdata); return 0; +err: + if (node) + devm_kfree(&client->dev, pdata); + return ret; } static int __devexit pm860x_remove(struct i2c_client *client) @@ -1238,11 +1269,24 @@ static int pm860x_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume); +static const struct i2c_device_id pm860x_id_table[] = { + { "88PM860x", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, pm860x_id_table); + +static const struct of_device_id pm860x_dt_ids[] = { + { .compatible = "marvell,88pm860x", }, + {}, +}; +MODULE_DEVICE_TABLE(of, pm860x_dt_ids); + static struct i2c_driver pm860x_driver = { .driver = { .name = "88PM860x", .owner = THIS_MODULE, .pm = &pm860x_pm_ops, + .of_match_table = of_match_ptr(pm860x_dt_ids), }, .probe = pm860x_probe, .remove = __devexit_p(pm860x_remove), diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index f96fbe38ff6f..1c5ab0172ea2 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -364,6 +366,34 @@ static struct pm8607_regulator_info pm8606_regulator_info[] = { PM8606_PREG(PREREGULATORB, 5), }; +#ifdef CONFIG_OF +static int pm8607_regulator_dt_init(struct platform_device *pdev, + struct pm8607_regulator_info *info, + struct regulator_config *config) +{ + struct device_node *nproot, *np; + nproot = pdev->dev.parent->of_node; + if (!nproot) + return -ENODEV; + nproot = of_find_node_by_name(nproot, "regulators"); + if (!nproot) { + dev_err(&pdev->dev, "failed to find regulators node\n"); + return -ENODEV; + } + for_each_child_of_node(nproot, np) { + if (!of_node_cmp(np->name, info->desc.name)) { + config->init_data = + of_get_regulator_init_data(&pdev->dev, np); + config->of_node = np; + break; + } + } + return 0; +} +#else +#define pm8607_regulator_dt_init(x, y, z) (-1) +#endif + static int __devinit pm8607_regulator_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -402,9 +432,12 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev) info->slope_double = 1; config.dev = &pdev->dev; - config.init_data = pdata; config.driver_data = info; + if (pm8607_regulator_dt_init(pdev, info, &config)) + if (pdata) + config.init_data = pdata; + if (chip->id == CHIP_PM8607) config.regmap = chip->regmap; else diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index feddefc42109..de9e854b326a 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -284,6 +285,28 @@ out: } #endif +#ifdef CONFIG_OF +static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev, + struct pm860x_rtc_info *info) +{ + struct device_node *np = pdev->dev.parent->of_node; + int ret; + if (!np) + return -ENODEV; + np = of_find_node_by_name(np, "rtc"); + if (!np) { + dev_err(&pdev->dev, "failed to find rtc node\n"); + return -ENODEV; + } + ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc); + if (ret) + info->vrtc = 0; + return 0; +} +#else +#define pm860x_rtc_dt_init(x, y) (-1) +#endif + static int __devinit pm860x_rtc_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -294,8 +317,6 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev) int ret; pdata = pdev->dev.platform_data; - if (pdata == NULL) - dev_warn(&pdev->dev, "No platform data!\n"); info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); if (!info) @@ -345,9 +366,11 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev) } } rtc_tm_to_time(&tm, &ticks); - if (pdata && pdata->sync) { - pdata->sync(ticks); - info->sync = pdata->sync; + if (pm860x_rtc_dt_init(pdev, info)) { + if (pdata && pdata->sync) { + pdata->sync(ticks); + info->sync = pdata->sync; + } } info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, @@ -366,10 +389,12 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev) #ifdef VRTC_CALIBRATION /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ - if (pdata && pdata->vrtc) - info->vrtc = pdata->vrtc & 0x3; - else - info->vrtc = 1; + if (pm860x_rtc_dt_init(pdev, info)) { + if (pdata && pdata->vrtc) + info->vrtc = pdata->vrtc & 0x3; + else + info->vrtc = 1; + } pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); /* calibrate VRTC */ diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 965161cacefa..b7ec34c57f46 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -159,6 +160,36 @@ static const struct backlight_ops pm860x_backlight_ops = { .get_brightness = pm860x_backlight_get_brightness, }; +#ifdef CONFIG_OF +static int pm860x_backlight_dt_init(struct platform_device *pdev, + struct pm860x_backlight_data *data, + char *name) +{ + struct device_node *nproot = pdev->dev.parent->of_node, *np; + int iset = 0; + if (!nproot) + return -ENODEV; + nproot = of_find_node_by_name(nproot, "backlights"); + if (!nproot) { + dev_err(&pdev->dev, "failed to find backlights node\n"); + return -ENODEV; + } + for_each_child_of_node(nproot, np) { + if (!of_node_cmp(np->name, name)) { + of_property_read_u32(np, "marvell,88pm860x-iset", + &iset); + data->iset = PM8606_WLED_CURRENT(iset); + of_property_read_u32(np, "marvell,88pm860x-pwm", + &data->pwm); + break; + } + } + return 0; +} +#else +#define pm860x_backlight_dt_init(x, y, z) (-1) +#endif + static int pm860x_backlight_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -203,9 +234,11 @@ static int pm860x_backlight_probe(struct platform_device *pdev) data->i2c = (chip->id == CHIP_PM8606) ? chip->client \ : chip->companion; data->current_brightness = MAX_BRIGHTNESS; - if (pdata) { - data->pwm = pdata->pwm; - data->iset = pdata->iset; + if (pm860x_backlight_dt_init(pdev, data, name)) { + if (pdata) { + data->pwm = pdata->pwm; + data->iset = pdata->iset; + } } memset(&props, 0, sizeof(struct backlight_properties)); diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index d515e5c438f0..ef3e6b701179 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -306,7 +306,7 @@ struct pm860x_chip { struct regmap *regmap_companion; int buck3_double; /* DVC ramp slope double */ - unsigned short companion_addr; + int companion_addr; unsigned short osc_vote; int id; int irq_mode; @@ -376,7 +376,7 @@ struct pm860x_platform_data { struct regulator_init_data *ldo_vibrator; struct regulator_init_data *ldo14; - unsigned short companion_addr; /* I2C address of companion chip */ + int companion_addr; /* I2C address of companion chip */ int i2c_port; /* Controlled by GI2C or PI2C */ int irq_mode; /* Clear interrupt by read/write(0/1) */ int irq_base; /* IRQ base number of 88pm860x */ -- cgit v1.2.3