diff options
author | Bengt Jonsson <bengt.g.jonsson@stericsson.com> | 2011-03-30 14:11:27 +0200 |
---|---|---|
committer | Henrik CARLING <henrik.carling@stericsson.com> | 2011-03-30 20:58:53 +0200 |
commit | 984cc7fd240a26262e1608c066eeeb2a4ece8dde (patch) | |
tree | be60b5f472ddaeed8c640998bce1dbce6de5c056 | |
parent | 22d5089814fb52bbb9bdcf106685cf2d9374e86e (diff) |
regulator Added regulator for sysclkreq and connected BT and WLANu8500-android-2.3_v0.48
ST-Ericsson Linux next: -
ST-Ericsson ID: ER 324615
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I616eda9d8e292c05dd8094d8085f5b488ee90396
Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/19533
Reviewed-by: Par-Gunnar HJALMDAHL <par-gunnar.p.hjalmdahl@stericsson.com>
Reviewed-by: Yvan FILLION <yvan.fillion@stericsson.com>
Tested-by: Yvan FILLION <yvan.fillion@stericsson.com>
Reviewed-by: Henrik CARLING <henrik.carling@stericsson.com>
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-regulators.c | 98 | ||||
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-ux500/virt-regulator-u8500.c | 58 | ||||
-rw-r--r-- | drivers/gpio/ab8500-gpio.c | 63 | ||||
-rw-r--r-- | drivers/regulator/ab8500.c | 114 | ||||
-rw-r--r-- | include/linux/mfd/ab8500/ab8500-gpio.h | 7 | ||||
-rw-r--r-- | include/linux/regulator/ab8500.h | 2 |
7 files changed, 296 insertions, 52 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 40ddd4745a7..7e742dc40f4 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c @@ -260,7 +260,7 @@ static struct regulator_consumer_supply ab8500_vana_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.10", + .dev_name = "reg-virt-consumer.9", .supply = "ana", }, #endif @@ -474,6 +474,34 @@ static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { }; +/* supply for CG2900 */ +static struct regulator_consumer_supply ab8500_sysclkreq_2_consumers[] = { + { + .dev_name = "cg2900-uart.0", + .supply = "gbf_1v8", + }, +#ifdef CONFIG_U8500_REGULATOR_DEBUG + { + .dev_name = "reg-virt-consumer.10", + .supply = "sysclkreq-2", + }, +#endif +}; + +/* supply for CW1200 */ +static struct regulator_consumer_supply ab8500_sysclkreq_4_consumers[] = { + { + .dev_name = "cw1200", + .supply = "wlan_1v8", + }, +#ifdef CONFIG_U8500_REGULATOR_DEBUG + { + .dev_name = "reg-virt-consumer.11", + .supply = "sysclkreq-4", + }, +#endif +}; + /* * AB8500 regulators */ @@ -581,6 +609,26 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), .consumer_supplies = ab8500_vana_consumers, }, + /* sysclkreq 2 pin */ + [AB8500_SYSCLKREQ_2] = { + .constraints = { + .name = "ab8500-sysclkreq-2", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = + ARRAY_SIZE(ab8500_sysclkreq_2_consumers), + .consumer_supplies = ab8500_sysclkreq_2_consumers, + }, + /* sysclkreq 4 pin */ + [AB8500_SYSCLKREQ_4] = { + .constraints = { + .name = "ab8500-sysclkreq-4", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = + ARRAY_SIZE(ab8500_sysclkreq_4_consumers), + .consumer_supplies = ab8500_sysclkreq_4_consumers, + }, }; /* @@ -652,7 +700,7 @@ static struct regulator_consumer_supply u8500_vape_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.10", + .dev_name = "reg-virt-consumer.12", .supply = "test", }, #endif @@ -678,7 +726,7 @@ struct regulator_init_data u8500_vape_regulator = { static struct regulator_consumer_supply u8500_varm_consumers[] = { #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.11", + .dev_name = "reg-virt-consumer.13", .supply = "test", }, #endif @@ -697,7 +745,7 @@ struct regulator_init_data u8500_varm_regulator = { static struct regulator_consumer_supply u8500_vmodem_consumers[] = { #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.12", + .dev_name = "reg-virt-consumer.14", .supply = "test", }, #endif @@ -716,7 +764,7 @@ struct regulator_init_data u8500_vmodem_regulator = { static struct regulator_consumer_supply u8500_vpll_consumers[] = { #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.13", + .dev_name = "reg-virt-consumer.15", .supply = "test", }, #endif @@ -735,7 +783,7 @@ struct regulator_init_data u8500_vpll_regulator = { static struct regulator_consumer_supply u8500_vsmps1_consumers[] = { #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.14", + .dev_name = "reg-virt-consumer.16", .supply = "test", }, #endif @@ -753,14 +801,6 @@ struct regulator_init_data u8500_vsmps1_regulator = { /* vsmsp2 regulator configuration */ static struct regulator_consumer_supply u8500_vsmps2_consumers[] = { { - .dev_name = "cg2900-uart.0", - .supply = "gbf_1v8", - }, - { - .dev_name = "cw1200", - .supply = "wlan_1v8", - }, - { .dev_name = "ab8500-usb.0", .supply = "musb_1v8", }, @@ -770,7 +810,7 @@ static struct regulator_consumer_supply u8500_vsmps2_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.15", + .dev_name = "reg-virt-consumer.17", .supply = "test", }, #endif @@ -789,7 +829,7 @@ struct regulator_init_data u8500_vsmps2_regulator = { static struct regulator_consumer_supply u8500_vsmps3_consumers[] = { #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.16", + .dev_name = "reg-virt-consumer.18", .supply = "test", }, #endif @@ -808,7 +848,7 @@ struct regulator_init_data u8500_vsmps3_regulator = { static struct regulator_consumer_supply u8500_vrf1_consumers[] = { #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.17", + .dev_name = "reg-virt-consumer.19", .supply = "test", }, #endif @@ -839,7 +879,7 @@ static struct regulator_consumer_supply u8500_svammdsp_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.18", + .dev_name = "reg-virt-consumer.20", .supply = "test", }, #endif @@ -863,7 +903,7 @@ static struct regulator_consumer_supply u8500_svammdspret_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.19", + .dev_name = "reg-virt-consumer.21", .supply = "test", }, #endif @@ -891,7 +931,7 @@ static struct regulator_consumer_supply u8500_svapipe_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.20", + .dev_name = "reg-virt-consumer.22", .supply = "test", }, #endif @@ -919,7 +959,7 @@ static struct regulator_consumer_supply u8500_siammdsp_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.21", + .dev_name = "reg-virt-consumer.23", .supply = "test", }, #endif @@ -943,7 +983,7 @@ static struct regulator_consumer_supply u8500_siammdspret_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.22", + .dev_name = "reg-virt-consumer.24", .supply = "test", }, #endif @@ -971,7 +1011,7 @@ static struct regulator_consumer_supply u8500_siapipe_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.23", + .dev_name = "reg-virt-consumer.25", .supply = "test", }, #endif @@ -1003,7 +1043,7 @@ static struct regulator_consumer_supply u8500_sga_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.24", + .dev_name = "reg-virt-consumer.26", .supply = "test", }, #endif @@ -1039,7 +1079,7 @@ static struct regulator_consumer_supply u8500_b2r2_mcde_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.25", + .dev_name = "reg-virt-consumer.27", .supply = "test", }, #endif @@ -1071,7 +1111,7 @@ static struct regulator_consumer_supply u8500_esram12_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.26", + .dev_name = "reg-virt-consumer.28", .supply = "test", }, #endif @@ -1099,7 +1139,7 @@ static struct regulator_consumer_supply u8500_esram12ret_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.27", + .dev_name = "reg-virt-consumer.29", .supply = "test", }, #endif @@ -1134,7 +1174,7 @@ static struct regulator_consumer_supply u8500_esram34_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.28", + .dev_name = "reg-virt-consumer.30", .supply = "test", }, #endif @@ -1162,7 +1202,7 @@ static struct regulator_consumer_supply u8500_esram34ret_consumers[] = { }, #ifdef CONFIG_U8500_REGULATOR_DEBUG { - .dev_name = "reg-virt-consumer.29", + .dev_name = "reg-virt-consumer.31", .supply = "test", }, #endif diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 7abdb59f6ae..215b033380f 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -767,7 +767,9 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { * register. This is the array of 7 configuration settings. * One has to compile time decide these settings. Below is the * explaination of these setting - * GpioSel1 = 0x02 => Pin GPIO2 (SysClkReq3) is configured as GPIO + * GpioSel1 = 0x07 => Pin GPIO1 (SysClkReq2) + * Pin GPIO2 (SysClkReq3) + * Pin GPIO3 (SysClkReq4) are configured as GPIO * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO @@ -776,7 +778,7 @@ static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured * as GPIO then this register selectes the alternate fucntions */ - .config_reg = {0x02, 0x1E, 0x80, 0x01, + .config_reg = {0x07, 0x1E, 0x80, 0x01, 0x7A, 0x02, 0x00}, }; #endif diff --git a/arch/arm/mach-ux500/virt-regulator-u8500.c b/arch/arm/mach-ux500/virt-regulator-u8500.c index d02d30ec9aa..4915a4cf636 100644 --- a/arch/arm/mach-ux500/virt-regulator-u8500.c +++ b/arch/arm/mach-ux500/virt-regulator-u8500.c @@ -96,12 +96,28 @@ static struct platform_device u8500_ana_virtual_regulator_device = { }, }; +static struct platform_device u8500_sysclkreq_2_virtual_regulator_device = { + .name = "reg-virt-consumer", + .id = 10, + .dev = { + .platform_data = "sysclkreq-2", + }, +}; + +static struct platform_device u8500_sysclkreq_4_virtual_regulator_device = { + .name = "reg-virt-consumer", + .id = 11, + .dev = { + .platform_data = "sysclkreq-4", + }, +}; + /* * Configuration for other U8500 virtual regulators */ static struct platform_device u8500_ape_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 10, + .id = 12, .dev = { .platform_data = "test", }, @@ -109,7 +125,7 @@ static struct platform_device u8500_ape_virtual_regulator_device = { static struct platform_device u8500_arm_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 11, + .id = 13, .dev = { .platform_data = "test", }, @@ -117,7 +133,7 @@ static struct platform_device u8500_arm_virtual_regulator_device = { static struct platform_device u8500_modem_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 12, + .id = 14, .dev = { .platform_data = "test", }, @@ -125,7 +141,7 @@ static struct platform_device u8500_modem_virtual_regulator_device = { static struct platform_device u8500_pll_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 13, + .id = 15, .dev = { .platform_data = "test", }, @@ -133,7 +149,7 @@ static struct platform_device u8500_pll_virtual_regulator_device = { static struct platform_device u8500_smps1_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 14, + .id = 16, .dev = { .platform_data = "test", }, @@ -141,7 +157,7 @@ static struct platform_device u8500_smps1_virtual_regulator_device = { static struct platform_device u8500_smps2_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 15, + .id = 17, .dev = { .platform_data = "test", }, @@ -149,7 +165,7 @@ static struct platform_device u8500_smps2_virtual_regulator_device = { static struct platform_device u8500_smps3_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 16, + .id = 18, .dev = { .platform_data = "test", }, @@ -157,7 +173,7 @@ static struct platform_device u8500_smps3_virtual_regulator_device = { static struct platform_device u8500_rf1_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 17, + .id = 19, .dev = { .platform_data = "test", }, @@ -168,7 +184,7 @@ static struct platform_device u8500_rf1_virtual_regulator_device = { */ static struct platform_device u8500_sva_mmdsp_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 18, + .id = 20, .dev = { .platform_data = "test", }, @@ -176,7 +192,7 @@ static struct platform_device u8500_sva_mmdsp_virtual_regulator_device = { static struct platform_device u8500_sva_mmdsp_ret_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 19, + .id = 21, .dev = { .platform_data = "test", }, @@ -184,7 +200,7 @@ static struct platform_device u8500_sva_mmdsp_ret_virtual_regulator_device = { static struct platform_device u8500_sva_pipe_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 20, + .id = 22, .dev = { .platform_data = "test", }, @@ -192,7 +208,7 @@ static struct platform_device u8500_sva_pipe_virtual_regulator_device = { static struct platform_device u8500_sia_mmdsp_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 21, + .id = 23, .dev = { .platform_data = "test", }, @@ -200,7 +216,7 @@ static struct platform_device u8500_sia_mmdsp_virtual_regulator_device = { static struct platform_device u8500_sia_mmdsp_ret_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 22, + .id = 24, .dev = { .platform_data = "test", }, @@ -208,7 +224,7 @@ static struct platform_device u8500_sia_mmdsp_ret_virtual_regulator_device = { static struct platform_device u8500_sia_pipe_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 23, + .id = 25, .dev = { .platform_data = "test", }, @@ -216,7 +232,7 @@ static struct platform_device u8500_sia_pipe_virtual_regulator_device = { static struct platform_device u8500_sga_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 24, + .id = 26, .dev = { .platform_data = "test", }, @@ -224,7 +240,7 @@ static struct platform_device u8500_sga_virtual_regulator_device = { static struct platform_device u8500_b2r2_mcde_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 25, + .id = 27, .dev = { .platform_data = "test", }, @@ -232,7 +248,7 @@ static struct platform_device u8500_b2r2_mcde_virtual_regulator_device = { static struct platform_device u8500_esram12_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 26, + .id = 28, .dev = { .platform_data = "test", }, @@ -240,7 +256,7 @@ static struct platform_device u8500_esram12_virtual_regulator_device = { static struct platform_device u8500_esram12_ret_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 27, + .id = 29, .dev = { .platform_data = "test", }, @@ -248,7 +264,7 @@ static struct platform_device u8500_esram12_ret_virtual_regulator_device = { static struct platform_device u8500_esram34_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 28, + .id = 30, .dev = { .platform_data = "test", }, @@ -256,7 +272,7 @@ static struct platform_device u8500_esram34_virtual_regulator_device = { static struct platform_device u8500_esram34_ret_virtual_regulator_device = { .name = "reg-virt-consumer", - .id = 29, + .id = 31, .dev = { .platform_data = "test", }, @@ -273,6 +289,8 @@ static struct platform_device *u8500_virtual_regulator_devices[] = { &u8500_anamic2_virtual_regulator_device, &u8500_dmic_virtual_regulator_device, &u8500_ana_virtual_regulator_device, + &u8500_sysclkreq_2_virtual_regulator_device, + &u8500_sysclkreq_4_virtual_regulator_device, &u8500_ape_virtual_regulator_device, &u8500_arm_virtual_regulator_device, &u8500_modem_virtual_regulator_device, diff --git a/drivers/gpio/ab8500-gpio.c b/drivers/gpio/ab8500-gpio.c index e276bea49b9..262151a7400 100644 --- a/drivers/gpio/ab8500-gpio.c +++ b/drivers/gpio/ab8500-gpio.c @@ -506,6 +506,69 @@ int ab8500_config_pull_up_or_down(struct device *dev, } EXPORT_SYMBOL(ab8500_config_pull_up_or_down); +/* + * ab8500_gpio_config_select() + * + * Configure functionality of pin, either specific use or GPIO. + * @dev: device pointer + * @gpio: gpio number + * @gpio_select: true if the pin should be used as GPIO + */ +int ab8500_gpio_config_select(struct device *dev, + unsigned gpio, bool gpio_select) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 reg = AB8500_GPIO_SEL1_REG + (offset / 8); + u8 pos = offset % 8; + u8 val = gpio_select ? 1 : 0; + int ret; + + ret = abx500_mask_and_set_register_interruptible(dev, + AB8500_MISC, reg, 1 << pos, val << pos); + if (ret < 0) + dev_err(dev, "%s write failed\n", __func__); + + dev_vdbg(dev, "%s (bank, addr, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, AB8500_MISC, reg, 1 << pos, val << pos); + + return ret; +} + +/* + * ab8500_gpio_config_get_select() + * + * Configure functionality of pin, either specific use or GPIO. + * @dev: device pointer + * @gpio: gpio number + * @gpio_select: pointer to pin selection status + */ +int ab8500_gpio_config_get_select(struct device *dev, + unsigned gpio, bool *gpio_select) +{ + u8 offset = gpio - AB8500_PIN_GPIO1; + u8 reg = AB8500_GPIO_SEL1_REG + (offset / 8); + u8 pos = offset % 8; + u8 val; + int ret; + + ret = abx500_get_register_interruptible(dev, + AB8500_MISC, reg, &val); + if (ret < 0) { + dev_err(dev, "%s read failed\n", __func__); + return ret; + } + + if (val & (1 << pos)) + *gpio_select = true; + else + *gpio_select = false; + + dev_vdbg(dev, "%s (bank, addr, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", + __func__, AB8500_MISC, reg, 1 << pos, val); + + return 0; +} + static struct platform_driver ab8500_gpio_driver = { .driver = { .name = "ab8500-gpio", diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index d4d8c641378..6cc76430824 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -21,6 +21,8 @@ #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/regulator/ab8500.h> +#include <linux/mfd/ab8500/ab8500-gpio.h> /* for sysclkreq pins */ +#include <mach/gpio.h> /* for sysclkreq pins */ /** * struct ab8500_regulator_info - ab8500 regulator information @@ -40,6 +42,7 @@ * @voltages: supported voltage table * @voltages_len: number of supported voltages for the regulator * @delay: startup delay in ms + * @gpio_pin: gpio pin number (for sysclkreq regulator only) */ struct ab8500_regulator_info { struct device *dev; @@ -58,6 +61,7 @@ struct ab8500_regulator_info { int const *voltages; int voltages_len; unsigned int delay; + unsigned int gpio_pin; }; /* voltage tables for the vauxn/vintcore supplies */ @@ -325,6 +329,88 @@ static struct regulator_ops ab8500_regulator_fixed_ops = { .list_voltage = ab8500_list_voltage, }; +static int ab8500_sysclkreq_enable(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = ab8500_gpio_config_select(info->dev, info->gpio_pin, false); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't set sysclkreq pin selection\n"); + return ret; + } + + dev_vdbg(rdev_get_dev(rdev), + "%s-enable (gpio_pin, gpio_select): %i, false\n", + info->desc.name, info->gpio_pin); + + return ret; +} + +static int ab8500_sysclkreq_disable(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = ab8500_gpio_config_select(info->dev, info->gpio_pin, true); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't set gpio pin selection\n"); + return ret; + } + + dev_vdbg(rdev_get_dev(rdev), + "%s-disable (gpio_pin, gpio_select): %i, true\n", + info->desc.name, info->gpio_pin); + + return ret; +} + +static int ab8500_sysclkreq_is_enabled(struct regulator_dev *rdev) +{ + int ret; + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + bool gpio_select; + + if (info == NULL) { + dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); + return -EINVAL; + } + + ret = ab8500_gpio_config_get_select(info->dev, info->gpio_pin, + &gpio_select); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't read gpio pin selection\n"); + return ret; + } + + dev_vdbg(rdev_get_dev(rdev), + "%s-is_enabled (gpio_pin, is_enabled): %i, %i\n", + info->desc.name, info->gpio_pin, !gpio_select); + + return !gpio_select; +} + +static struct regulator_ops ab8500_sysclkreq_ops = { + .enable = ab8500_sysclkreq_enable, + .disable = ab8500_sysclkreq_disable, + .is_enabled = ab8500_sysclkreq_is_enabled, + .get_voltage = ab8500_fixed_get_voltage, + .list_voltage = ab8500_list_voltage, +}; + static struct ab8500_regulator_info ab8500_regulator_info[AB8500_NUM_REGULATORS] = { /* @@ -510,7 +596,33 @@ static struct ab8500_regulator_info .update_val_enable = 0x04, }, - + /* + * SysClkReq regulators + */ + [AB8500_SYSCLKREQ_2] = { + .desc = { + .name = "SYSCLKREQ-2", + .ops = &ab8500_sysclkreq_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_SYSCLKREQ_2, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 1, /* bogus value */ + .gpio_pin = AB8500_PIN_GPIO1, + }, + [AB8500_SYSCLKREQ_4] = { + .desc = { + .name = "SYSCLKREQ-4", + .ops = &ab8500_sysclkreq_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_SYSCLKREQ_4, + .owner = THIS_MODULE, + .n_voltages = 1, + }, + .fixed_uV = 1, /* bogus value */ + .gpio_pin = AB8500_PIN_GPIO3, + }, }; struct ab8500_reg_init { diff --git a/include/linux/mfd/ab8500/ab8500-gpio.h b/include/linux/mfd/ab8500/ab8500-gpio.h index 472de6a2ee2..abb407cd57f 100644 --- a/include/linux/mfd/ab8500/ab8500-gpio.h +++ b/include/linux/mfd/ab8500/ab8500-gpio.h @@ -20,4 +20,11 @@ struct ab8500_gpio_platform_data { int ab8500_config_pull_up_or_down(struct device *dev, unsigned gpio, bool enable); + +int ab8500_gpio_config_select(struct device *dev, + unsigned gpio, bool gpio_select); + +int ab8500_gpio_config_get_select(struct device *dev, + unsigned gpio, bool *gpio_select); + #endif /* _AB8500_GPIO_H */ diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h index 81573443588..cfc307d73ff 100644 --- a/include/linux/regulator/ab8500.h +++ b/include/linux/regulator/ab8500.h @@ -22,6 +22,8 @@ enum ab8500_regulator_id { AB8500_LDO_ANAMIC2, AB8500_LDO_DMIC, AB8500_LDO_ANA, + AB8500_SYSCLKREQ_2, + AB8500_SYSCLKREQ_4, AB8500_NUM_REGULATORS, }; |