aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2012-02-20 15:42:24 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-03-06 12:46:43 -0500
commitd6255529b2639de542324f314b93939b7996a7c5 (patch)
tree42230a2b9e8f02382735be716973677545e204b9 /drivers/mfd
parent2ced445e2ddf65f484a489161accddf475676965 (diff)
mfd: Support AB9540 ab8500 variant
The AB9540 variant of the AB8500 is basically close enough to use the same driver. This adds the new registers and deviations for this new chip variant. Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Maxime Coquelin <maxime.coquelin@stericsson.com> Signed-off-by: Alex Macro <alex.macro@stericsson.com> Signed-off-by: Michel Jaouen <michel.jaouen@stericsson.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/ab8500-core.c191
1 files changed, 170 insertions, 21 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 73907ad1e3d3..15a18fee9713 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -32,6 +32,7 @@
32#define AB8500_IT_SOURCE6_REG 0x05 32#define AB8500_IT_SOURCE6_REG 0x05
33#define AB8500_IT_SOURCE7_REG 0x06 33#define AB8500_IT_SOURCE7_REG 0x06
34#define AB8500_IT_SOURCE8_REG 0x07 34#define AB8500_IT_SOURCE8_REG 0x07
35#define AB9540_IT_SOURCE13_REG 0x0C
35#define AB8500_IT_SOURCE19_REG 0x12 36#define AB8500_IT_SOURCE19_REG 0x12
36#define AB8500_IT_SOURCE20_REG 0x13 37#define AB8500_IT_SOURCE20_REG 0x13
37#define AB8500_IT_SOURCE21_REG 0x14 38#define AB8500_IT_SOURCE21_REG 0x14
@@ -53,6 +54,7 @@
53#define AB8500_IT_LATCH9_REG 0x28 54#define AB8500_IT_LATCH9_REG 0x28
54#define AB8500_IT_LATCH10_REG 0x29 55#define AB8500_IT_LATCH10_REG 0x29
55#define AB8500_IT_LATCH12_REG 0x2B 56#define AB8500_IT_LATCH12_REG 0x2B
57#define AB9540_IT_LATCH13_REG 0x2C
56#define AB8500_IT_LATCH19_REG 0x32 58#define AB8500_IT_LATCH19_REG 0x32
57#define AB8500_IT_LATCH20_REG 0x33 59#define AB8500_IT_LATCH20_REG 0x33
58#define AB8500_IT_LATCH21_REG 0x34 60#define AB8500_IT_LATCH21_REG 0x34
@@ -95,6 +97,9 @@
95 97
96#define AB8500_TURN_ON_STATUS 0x00 98#define AB8500_TURN_ON_STATUS 0x00
97 99
100#define AB9540_MODEM_CTRL2_REG 0x23
101#define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT BIT(2)
102
98/* 103/*
99 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt 104 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
100 * numbers are indexed into this array with (num / 8). The interupts are 105 * numbers are indexed into this array with (num / 8). The interupts are
@@ -108,6 +113,11 @@ static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = {
108 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 113 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21,
109}; 114};
110 115
116/* AB9540 support */
117static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = {
118 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, 12, 13, 24,
119};
120
111static const char ab8500_version_str[][7] = { 121static const char ab8500_version_str[][7] = {
112 [AB8500_VERSION_AB8500] = "AB8500", 122 [AB8500_VERSION_AB8500] = "AB8500",
113 [AB8500_VERSION_AB8505] = "AB8505", 123 [AB8500_VERSION_AB8505] = "AB8505",
@@ -354,7 +364,10 @@ static int ab8500_irq_init(struct ab8500 *ab8500)
354 int irq; 364 int irq;
355 int num_irqs; 365 int num_irqs;
356 366
357 num_irqs = AB8500_NR_IRQS; 367 if (is_ab9540(ab8500))
368 num_irqs = AB9540_NR_IRQS;
369 else
370 num_irqs = AB8500_NR_IRQS;
358 371
359 for (irq = base; irq < base + num_irqs; irq++) { 372 for (irq = base; irq < base + num_irqs; irq++) {
360 irq_set_chip_data(irq, ab8500); 373 irq_set_chip_data(irq, ab8500);
@@ -377,7 +390,10 @@ static void ab8500_irq_remove(struct ab8500 *ab8500)
377 int irq; 390 int irq;
378 int num_irqs; 391 int num_irqs;
379 392
380 num_irqs = AB8500_NR_IRQS; 393 if (is_ab9540(ab8500))
394 num_irqs = AB9540_NR_IRQS;
395 else
396 num_irqs = AB8500_NR_IRQS;
381 397
382 for (irq = base; irq < base + num_irqs; irq++) { 398 for (irq = base; irq < base + num_irqs; irq++) {
383#ifdef CONFIG_ARM 399#ifdef CONFIG_ARM
@@ -388,6 +404,7 @@ static void ab8500_irq_remove(struct ab8500 *ab8500)
388 } 404 }
389} 405}
390 406
407/* AB8500 GPIO Resources */
391static struct resource __devinitdata ab8500_gpio_resources[] = { 408static struct resource __devinitdata ab8500_gpio_resources[] = {
392 { 409 {
393 .name = "GPIO_INT6", 410 .name = "GPIO_INT6",
@@ -397,6 +414,28 @@ static struct resource __devinitdata ab8500_gpio_resources[] = {
397 } 414 }
398}; 415};
399 416
417/* AB9540 GPIO Resources */
418static struct resource __devinitdata ab9540_gpio_resources[] = {
419 {
420 .name = "GPIO_INT6",
421 .start = AB8500_INT_GPIO6R,
422 .end = AB8500_INT_GPIO41F,
423 .flags = IORESOURCE_IRQ,
424 },
425 {
426 .name = "GPIO_INT14",
427 .start = AB9540_INT_GPIO50R,
428 .end = AB9540_INT_GPIO54R,
429 .flags = IORESOURCE_IRQ,
430 },
431 {
432 .name = "GPIO_INT15",
433 .start = AB9540_INT_GPIO50F,
434 .end = AB9540_INT_GPIO54F,
435 .flags = IORESOURCE_IRQ,
436 }
437};
438
400static struct resource __devinitdata ab8500_gpadc_resources[] = { 439static struct resource __devinitdata ab8500_gpadc_resources[] = {
401 { 440 {
402 .name = "HW_CONV_END", 441 .name = "HW_CONV_END",
@@ -713,7 +752,7 @@ static struct resource __devinitdata ab8500_temp_resources[] = {
713 }, 752 },
714}; 753};
715 754
716static struct mfd_cell __devinitdata ab8500_devs[] = { 755static struct mfd_cell __devinitdata abx500_common_devs[] = {
717#ifdef CONFIG_DEBUG_FS 756#ifdef CONFIG_DEBUG_FS
718 { 757 {
719 .name = "ab8500-debug", 758 .name = "ab8500-debug",
@@ -728,11 +767,6 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
728 .name = "ab8500-regulator", 767 .name = "ab8500-regulator",
729 }, 768 },
730 { 769 {
731 .name = "ab8500-gpio",
732 .num_resources = ARRAY_SIZE(ab8500_gpio_resources),
733 .resources = ab8500_gpio_resources,
734 },
735 {
736 .name = "ab8500-gpadc", 770 .name = "ab8500-gpadc",
737 .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), 771 .num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
738 .resources = ab8500_gpadc_resources, 772 .resources = ab8500_gpadc_resources,
@@ -770,11 +804,7 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
770 { 804 {
771 .name = "ab8500-codec", 805 .name = "ab8500-codec",
772 }, 806 },
773 { 807
774 .name = "ab8500-usb",
775 .num_resources = ARRAY_SIZE(ab8500_usb_resources),
776 .resources = ab8500_usb_resources,
777 },
778 { 808 {
779 .name = "ab8500-poweron-key", 809 .name = "ab8500-poweron-key",
780 .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), 810 .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
@@ -803,6 +833,32 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
803 }, 833 },
804}; 834};
805 835
836static struct mfd_cell __devinitdata ab8500_devs[] = {
837 {
838 .name = "ab8500-gpio",
839 .num_resources = ARRAY_SIZE(ab8500_gpio_resources),
840 .resources = ab8500_gpio_resources,
841 },
842 {
843 .name = "ab8500-usb",
844 .num_resources = ARRAY_SIZE(ab8500_usb_resources),
845 .resources = ab8500_usb_resources,
846 },
847};
848
849static struct mfd_cell __devinitdata ab9540_devs[] = {
850 {
851 .name = "ab8500-gpio",
852 .num_resources = ARRAY_SIZE(ab9540_gpio_resources),
853 .resources = ab9540_gpio_resources,
854 },
855 {
856 .name = "ab9540-usb",
857 .num_resources = ARRAY_SIZE(ab8500_usb_resources),
858 .resources = ab8500_usb_resources,
859 },
860};
861
806static ssize_t show_chip_id(struct device *dev, 862static ssize_t show_chip_id(struct device *dev,
807 struct device_attribute *attr, char *buf) 863 struct device_attribute *attr, char *buf)
808{ 864{
@@ -864,9 +920,64 @@ static ssize_t show_turn_on_status(struct device *dev,
864 return sprintf(buf, "%#x\n", value); 920 return sprintf(buf, "%#x\n", value);
865} 921}
866 922
923static ssize_t show_ab9540_dbbrstn(struct device *dev,
924 struct device_attribute *attr, char *buf)
925{
926 struct ab8500 *ab8500;
927 int ret;
928 u8 value;
929
930 ab8500 = dev_get_drvdata(dev);
931
932 ret = get_register_interruptible(ab8500, AB8500_REGU_CTRL2,
933 AB9540_MODEM_CTRL2_REG, &value);
934 if (ret < 0)
935 return ret;
936
937 return sprintf(buf, "%d\n",
938 (value & AB9540_MODEM_CTRL2_SWDBBRSTN_BIT) ? 1 : 0);
939}
940
941static ssize_t store_ab9540_dbbrstn(struct device *dev,
942 struct device_attribute *attr, const char *buf, size_t count)
943{
944 struct ab8500 *ab8500;
945 int ret = count;
946 int err;
947 u8 bitvalues;
948
949 ab8500 = dev_get_drvdata(dev);
950
951 if (count > 0) {
952 switch (buf[0]) {
953 case '0':
954 bitvalues = 0;
955 break;
956 case '1':
957 bitvalues = AB9540_MODEM_CTRL2_SWDBBRSTN_BIT;
958 break;
959 default:
960 goto exit;
961 }
962
963 err = mask_and_set_register_interruptible(ab8500,
964 AB8500_REGU_CTRL2, AB9540_MODEM_CTRL2_REG,
965 AB9540_MODEM_CTRL2_SWDBBRSTN_BIT, bitvalues);
966 if (err)
967 dev_info(ab8500->dev,
968 "Failed to set DBBRSTN %c, err %#x\n",
969 buf[0], err);
970 }
971
972exit:
973 return ret;
974}
975
867static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); 976static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
868static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL); 977static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
869static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL); 978static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL);
979static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR,
980 show_ab9540_dbbrstn, store_ab9540_dbbrstn);
870 981
871static struct attribute *ab8500_sysfs_entries[] = { 982static struct attribute *ab8500_sysfs_entries[] = {
872 &dev_attr_chip_id.attr, 983 &dev_attr_chip_id.attr,
@@ -875,10 +986,22 @@ static struct attribute *ab8500_sysfs_entries[] = {
875 NULL, 986 NULL,
876}; 987};
877 988
989static struct attribute *ab9540_sysfs_entries[] = {
990 &dev_attr_chip_id.attr,
991 &dev_attr_switch_off_status.attr,
992 &dev_attr_turn_on_status.attr,
993 &dev_attr_dbbrstn.attr,
994 NULL,
995};
996
878static struct attribute_group ab8500_attr_group = { 997static struct attribute_group ab8500_attr_group = {
879 .attrs = ab8500_sysfs_entries, 998 .attrs = ab8500_sysfs_entries,
880}; 999};
881 1000
1001static struct attribute_group ab9540_attr_group = {
1002 .attrs = ab9540_sysfs_entries,
1003};
1004
882int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) 1005int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version)
883{ 1006{
884 struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); 1007 struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev);
@@ -915,8 +1038,14 @@ int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version)
915 ab8500->chip_id >> 4, 1038 ab8500->chip_id >> 4,
916 ab8500->chip_id & 0x0F); 1039 ab8500->chip_id & 0x0F);
917 1040
918 ab8500->mask_size = AB8500_NUM_IRQ_REGS; 1041 /* Configure AB8500 or AB9540 IRQ */
919 ab8500->irq_reg_offset = ab8500_irq_regoffset; 1042 if (is_ab9540(ab8500)) {
1043 ab8500->mask_size = AB9540_NUM_IRQ_REGS;
1044 ab8500->irq_reg_offset = ab9540_irq_regoffset;
1045 } else {
1046 ab8500->mask_size = AB8500_NUM_IRQ_REGS;
1047 ab8500->irq_reg_offset = ab8500_irq_regoffset;
1048 }
920 ab8500->mask = kzalloc(ab8500->mask_size, GFP_KERNEL); 1049 ab8500->mask = kzalloc(ab8500->mask_size, GFP_KERNEL);
921 if (!ab8500->mask) 1050 if (!ab8500->mask)
922 return -ENOMEM; 1051 return -ENOMEM;
@@ -982,17 +1111,34 @@ int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version)
982 goto out_removeirq; 1111 goto out_removeirq;
983 } 1112 }
984 1113
985 ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, 1114 ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs,
986 ARRAY_SIZE(ab8500_devs), NULL, 1115 ARRAY_SIZE(abx500_common_devs), NULL,
1116 ab8500->irq_base);
1117
1118 if (ret)
1119 goto out_freeirq;
1120
1121 if (is_ab9540(ab8500))
1122 ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
1123 ARRAY_SIZE(ab9540_devs), NULL,
1124 ab8500->irq_base);
1125 else
1126 ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
1127 ARRAY_SIZE(ab9540_devs), NULL,
987 ab8500->irq_base); 1128 ab8500->irq_base);
988 if (ret) 1129 if (ret)
989 goto out_freeirq; 1130 goto out_freeirq;
990 1131
991 ret = sysfs_create_group(&ab8500->dev->kobj, &ab8500_attr_group); 1132 if (is_ab9540(ab8500))
1133 ret = sysfs_create_group(&ab8500->dev->kobj,
1134 &ab9540_attr_group);
1135 else
1136 ret = sysfs_create_group(&ab8500->dev->kobj,
1137 &ab8500_attr_group);
992 if (ret) 1138 if (ret)
993 dev_err(ab8500->dev, "error creating sysfs entries\n"); 1139 dev_err(ab8500->dev, "error creating sysfs entries\n");
994 1140 else
995 return ret; 1141 return ret;
996 1142
997out_freeirq: 1143out_freeirq:
998 if (ab8500->irq_base) 1144 if (ab8500->irq_base)
@@ -1010,7 +1156,10 @@ out_freemask:
1010 1156
1011int __devexit ab8500_exit(struct ab8500 *ab8500) 1157int __devexit ab8500_exit(struct ab8500 *ab8500)
1012{ 1158{
1013 sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); 1159 if (is_ab9540(ab8500))
1160 sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group);
1161 else
1162 sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group);
1014 mfd_remove_devices(ab8500->dev); 1163 mfd_remove_devices(ab8500->dev);
1015 if (ab8500->irq_base) { 1164 if (ab8500->irq_base) {
1016 free_irq(ab8500->irq, ab8500); 1165 free_irq(ab8500->irq, ab8500);