diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 12:23:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 12:23:24 -0400 |
commit | 9bc747bea5fad819e0c0ad96e6a67ea0640dfe2b (patch) | |
tree | d500225e7a1c90a6bd17d3e63e2f6e781810db2b /drivers | |
parent | 32b908eea9e5ecd1049008e134eadbfcd0da5e38 (diff) | |
parent | 0e896b1ddc1905df904df98c204bacf028219729 (diff) |
Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull first batch of arm-soc cleanups from Olof Johansson:
"These cleanups are basically all over the place. The idea is to
collect changes with minimal impact but large number of changes so we
can avoid them from distracting in the diffstat in the other series.
A significant number of lines get removed here, in particular because
the ixp2000 and ixp23xx platforms get removed. These have never been
extremely popular and have fallen into disuse over time with no active
maintainer taking care of them. The u5500 soc never made it into a
product, so we are removing it from the ux500 platform.
Many good cleanups also went into the at91 and omap platforms, as has
been the case for a number of releases."
Trivial modify-delete conflicts in arch/arm/mach-{ixp2000,ixp23xx}
* tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (152 commits)
ARM: clps711x: Cleanup IRQ handling
ARM clps711x: Removed unused header mach/time.h
ARM: clps711x: Added note about support EP731x CPU to Kconfig
ARM: clps711x: Added missing register definitions
ARM: clps711x: Used own subarch directory for store header file
Dove: Fix Section mismatch warnings
ARM: orion5x: ts78xx debugging changes
ARM: orion5x: remove PM dependency from ts78xx
ARM: orion5x: ts78xx fix NAND resource off by one
ARM: orion5x: ts78xx whitespace cleanups
Orion5x: Fix Section mismatch warnings
Orion5x: Fix warning: struct pci_dev declared inside paramter list
ARM: clps711x: Combine header files into one for clps711x-targets
ARM: S3C24XX: Use common macro to define resources on mach-qt2410.c
ARM: S3C24XX: Use common macro to define resources on mach-osiris.c
ARM: EXYNOS: Adapt to cpuidle core time keeping and irq enable
ARM: S5PV210: Use common macro to define resources on mach-smdkv210.c
ARM: S5PV210: Use common macro to define resources on dev-audio.c
ARM: S5PC100: Use common macro to define resources on dev-audio.c
ARM: S5P64X0: Use common macro to define resources on dev-audio.c
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/hw_random/Kconfig | 2 | ||||
-rw-r--r-- | drivers/clocksource/Kconfig | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 4 | ||||
-rw-r--r-- | drivers/mfd/Kconfig | 27 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 3 | ||||
-rw-r--r-- | drivers/mfd/ab5500-core.c | 1439 | ||||
-rw-r--r-- | drivers/mfd/ab5500-debugfs.c | 807 | ||||
-rw-r--r-- | drivers/mfd/ab5500-debugfs.h | 22 | ||||
-rw-r--r-- | drivers/mfd/db5500-prcmu.c | 451 | ||||
-rw-r--r-- | drivers/mtd/nand/autcpu12.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/h1910.c | 2 | ||||
-rw-r--r-- | drivers/net/irda/Kconfig | 4 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 2 | ||||
-rw-r--r-- | drivers/tty/serial/clps711x.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-omap.c | 5 | ||||
-rw-r--r-- | drivers/video/clps711xfb.c | 1 | ||||
-rw-r--r-- | drivers/video/omap2/displays/Kconfig | 8 | ||||
-rw-r--r-- | drivers/video/omap2/displays/Makefile | 2 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-taal.c | 22 | ||||
-rw-r--r-- | drivers/video/omap2/displays/panel-tfp410.c (renamed from drivers/video/omap2/displays/panel-dvi.c) | 134 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 133 |
21 files changed, 186 insertions, 2895 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 0689bf6b0183..b2402eb076c7 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -62,7 +62,7 @@ config HW_RANDOM_AMD | |||
62 | 62 | ||
63 | config HW_RANDOM_ATMEL | 63 | config HW_RANDOM_ATMEL |
64 | tristate "Atmel Random Number Generator support" | 64 | tristate "Atmel Random Number Generator support" |
65 | depends on HW_RANDOM && ARCH_AT91SAM9G45 | 65 | depends on HW_RANDOM && HAVE_CLK |
66 | default HW_RANDOM | 66 | default HW_RANDOM |
67 | ---help--- | 67 | ---help--- |
68 | This driver provides kernel-side support for the Random Number | 68 | This driver provides kernel-side support for the Random Number |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 5138927a416c..99c6b203e6cd 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -18,7 +18,7 @@ config DW_APB_TIMER | |||
18 | 18 | ||
19 | config CLKSRC_DBX500_PRCMU | 19 | config CLKSRC_DBX500_PRCMU |
20 | bool "Clocksource PRCMU Timer" | 20 | bool "Clocksource PRCMU Timer" |
21 | depends on UX500_SOC_DB5500 || UX500_SOC_DB8500 | 21 | depends on UX500_SOC_DB8500 |
22 | default y | 22 | default y |
23 | help | 23 | help |
24 | Use the always on PRCMU Timer as clocksource | 24 | Use the always on PRCMU Timer as clocksource |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 2a2141915aa0..75838d7710ce 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -489,10 +489,10 @@ config TOUCHSCREEN_TI_TSCADC | |||
489 | 489 | ||
490 | config TOUCHSCREEN_ATMEL_TSADCC | 490 | config TOUCHSCREEN_ATMEL_TSADCC |
491 | tristate "Atmel Touchscreen Interface" | 491 | tristate "Atmel Touchscreen Interface" |
492 | depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 | 492 | depends on ARCH_AT91 |
493 | help | 493 | help |
494 | Say Y here if you have a 4-wire touchscreen connected to the | 494 | Say Y here if you have a 4-wire touchscreen connected to the |
495 | ADC Controller on your Atmel SoC (such as the AT91SAM9RL). | 495 | ADC Controller on your Atmel SoC. |
496 | 496 | ||
497 | If unsure, say N. | 497 | If unsure, say N. |
498 | 498 | ||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index b5a0032f616e..49ef8b0794ae 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -652,23 +652,6 @@ config EZX_PCAP | |||
652 | This enables the PCAP ASIC present on EZX Phones. This is | 652 | This enables the PCAP ASIC present on EZX Phones. This is |
653 | needed for MMC, TouchScreen, Sound, USB, etc.. | 653 | needed for MMC, TouchScreen, Sound, USB, etc.. |
654 | 654 | ||
655 | config AB5500_CORE | ||
656 | bool "ST-Ericsson AB5500 Mixed Signal Power Management chip" | ||
657 | depends on ABX500_CORE && MFD_DB5500_PRCMU | ||
658 | select MFD_CORE | ||
659 | help | ||
660 | Select this option to enable access to AB5500 power management | ||
661 | chip. This connects to the db5500 chip via the I2C bus via PRCMU. | ||
662 | This chip embeds various other multimedia funtionalities as well. | ||
663 | |||
664 | config AB5500_DEBUG | ||
665 | bool "Enable debug info via debugfs" | ||
666 | depends on AB5500_CORE && DEBUG_FS | ||
667 | default y if DEBUG_FS | ||
668 | help | ||
669 | Select this option if you want debug information from the AB5500 | ||
670 | using the debug filesystem, debugfs. | ||
671 | |||
672 | config AB8500_CORE | 655 | config AB8500_CORE |
673 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" | 656 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" |
674 | depends on GENERIC_HARDIRQS && ABX500_CORE | 657 | depends on GENERIC_HARDIRQS && ABX500_CORE |
@@ -715,16 +698,6 @@ config MFD_DB8500_PRCMU | |||
715 | system controller running an XP70 microprocessor, which is accessed | 698 | system controller running an XP70 microprocessor, which is accessed |
716 | through a register map. | 699 | through a register map. |
717 | 700 | ||
718 | config MFD_DB5500_PRCMU | ||
719 | bool "ST-Ericsson DB5500 Power Reset Control Management Unit" | ||
720 | depends on UX500_SOC_DB5500 | ||
721 | select MFD_CORE | ||
722 | help | ||
723 | Select this option to enable support for the DB5500 Power Reset | ||
724 | and Control Management Unit. This is basically an autonomous | ||
725 | system controller running an XP70 microprocessor, which is accessed | ||
726 | through a register map. | ||
727 | |||
728 | config MFD_CS5535 | 701 | config MFD_CS5535 |
729 | tristate "Support for CS5535 and CS5536 southbridge core functions" | 702 | tristate "Support for CS5535 and CS5536 southbridge core functions" |
730 | select MFD_CORE | 703 | select MFD_CORE |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 77293e150239..43672b87805a 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -87,15 +87,12 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o | |||
87 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o | 87 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o |
88 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o | 88 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o |
89 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o | 89 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o |
90 | obj-$(CONFIG_AB5500_CORE) += ab5500-core.o | ||
91 | obj-$(CONFIG_AB5500_DEBUG) += ab5500-debugfs.o | ||
92 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o | 90 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o |
93 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o | 91 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o |
94 | obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o | 92 | obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o |
95 | obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o | 93 | obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o |
96 | # ab8500-i2c need to come after db8500-prcmu (which provides the channel) | 94 | # ab8500-i2c need to come after db8500-prcmu (which provides the channel) |
97 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o | 95 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o |
98 | obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o | ||
99 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o | 96 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o |
100 | obj-$(CONFIG_PMIC_ADP5520) += adp5520.o | 97 | obj-$(CONFIG_PMIC_ADP5520) += adp5520.o |
101 | obj-$(CONFIG_LPC_SCH) += lpc_sch.o | 98 | obj-$(CONFIG_LPC_SCH) += lpc_sch.o |
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c deleted file mode 100644 index 54d0fe40845f..000000000000 --- a/drivers/mfd/ab5500-core.c +++ /dev/null | |||
@@ -1,1439 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Low-level core for exclusive access to the AB5500 IC on the I2C bus | ||
5 | * and some basic chip-configuration. | ||
6 | * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> | ||
7 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
8 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> | ||
9 | * Author: Rickard Andersson <rickard.andersson@stericsson.com> | ||
10 | * Author: Karl Komierowski <karl.komierowski@stericsson.com> | ||
11 | * Author: Bibek Basu <bibek.basu@stericsson.com> | ||
12 | * | ||
13 | * TODO: Event handling with irq_chip. Waiting for PRCMU fw support. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/mutex.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/irq.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/random.h> | ||
25 | #include <linux/mfd/abx500.h> | ||
26 | #include <linux/mfd/abx500/ab5500.h> | ||
27 | #include <linux/list.h> | ||
28 | #include <linux/bitops.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mfd/core.h> | ||
31 | #include <linux/mfd/db5500-prcmu.h> | ||
32 | |||
33 | #include "ab5500-core.h" | ||
34 | #include "ab5500-debugfs.h" | ||
35 | |||
36 | #define AB5500_NUM_EVENT_REG 23 | ||
37 | #define AB5500_IT_LATCH0_REG 0x40 | ||
38 | #define AB5500_IT_MASK0_REG 0x60 | ||
39 | |||
40 | /* | ||
41 | * Permissible register ranges for reading and writing per device and bank. | ||
42 | * | ||
43 | * The ranges must be listed in increasing address order, and no overlaps are | ||
44 | * allowed. It is assumed that write permission implies read permission | ||
45 | * (i.e. only RO and RW permissions should be used). Ranges with write | ||
46 | * permission must not be split up. | ||
47 | */ | ||
48 | |||
49 | #define NO_RANGE {.count = 0, .range = NULL,} | ||
50 | static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = { | ||
51 | [AB5500_DEVID_USB] = { | ||
52 | .nbanks = 1, | ||
53 | .bank = (struct ab5500_i2c_ranges []) { | ||
54 | { | ||
55 | .bankid = AB5500_BANK_USB, | ||
56 | .nranges = 12, | ||
57 | .range = (struct ab5500_reg_range[]) { | ||
58 | { | ||
59 | .first = 0x01, | ||
60 | .last = 0x01, | ||
61 | .perm = AB5500_PERM_RW, | ||
62 | }, | ||
63 | { | ||
64 | .first = 0x80, | ||
65 | .last = 0x83, | ||
66 | .perm = AB5500_PERM_RW, | ||
67 | }, | ||
68 | { | ||
69 | .first = 0x87, | ||
70 | .last = 0x8A, | ||
71 | .perm = AB5500_PERM_RW, | ||
72 | }, | ||
73 | { | ||
74 | .first = 0x8B, | ||
75 | .last = 0x8B, | ||
76 | .perm = AB5500_PERM_RO, | ||
77 | }, | ||
78 | { | ||
79 | .first = 0x91, | ||
80 | .last = 0x92, | ||
81 | .perm = AB5500_PERM_RO, | ||
82 | }, | ||
83 | { | ||
84 | .first = 0x93, | ||
85 | .last = 0x93, | ||
86 | .perm = AB5500_PERM_RW, | ||
87 | }, | ||
88 | { | ||
89 | .first = 0x94, | ||
90 | .last = 0x94, | ||
91 | .perm = AB5500_PERM_RO, | ||
92 | }, | ||
93 | { | ||
94 | .first = 0xA8, | ||
95 | .last = 0xB0, | ||
96 | .perm = AB5500_PERM_RO, | ||
97 | }, | ||
98 | { | ||
99 | .first = 0xB2, | ||
100 | .last = 0xB2, | ||
101 | .perm = AB5500_PERM_RO, | ||
102 | }, | ||
103 | { | ||
104 | .first = 0xB4, | ||
105 | .last = 0xBC, | ||
106 | .perm = AB5500_PERM_RO, | ||
107 | }, | ||
108 | { | ||
109 | .first = 0xBF, | ||
110 | .last = 0xBF, | ||
111 | .perm = AB5500_PERM_RO, | ||
112 | }, | ||
113 | { | ||
114 | .first = 0xC1, | ||
115 | .last = 0xC5, | ||
116 | .perm = AB5500_PERM_RO, | ||
117 | }, | ||
118 | }, | ||
119 | }, | ||
120 | }, | ||
121 | }, | ||
122 | [AB5500_DEVID_ADC] = { | ||
123 | .nbanks = 1, | ||
124 | .bank = (struct ab5500_i2c_ranges []) { | ||
125 | { | ||
126 | .bankid = AB5500_BANK_ADC, | ||
127 | .nranges = 6, | ||
128 | .range = (struct ab5500_reg_range[]) { | ||
129 | { | ||
130 | .first = 0x1F, | ||
131 | .last = 0x22, | ||
132 | .perm = AB5500_PERM_RO, | ||
133 | }, | ||
134 | { | ||
135 | .first = 0x23, | ||
136 | .last = 0x24, | ||
137 | .perm = AB5500_PERM_RW, | ||
138 | }, | ||
139 | { | ||
140 | .first = 0x26, | ||
141 | .last = 0x2D, | ||
142 | .perm = AB5500_PERM_RO, | ||
143 | }, | ||
144 | { | ||
145 | .first = 0x2F, | ||
146 | .last = 0x34, | ||
147 | .perm = AB5500_PERM_RW, | ||
148 | }, | ||
149 | { | ||
150 | .first = 0x37, | ||
151 | .last = 0x57, | ||
152 | .perm = AB5500_PERM_RW, | ||
153 | }, | ||
154 | { | ||
155 | .first = 0x58, | ||
156 | .last = 0x58, | ||
157 | .perm = AB5500_PERM_RO, | ||
158 | }, | ||
159 | }, | ||
160 | }, | ||
161 | }, | ||
162 | }, | ||
163 | [AB5500_DEVID_LEDS] = { | ||
164 | .nbanks = 1, | ||
165 | .bank = (struct ab5500_i2c_ranges []) { | ||
166 | { | ||
167 | .bankid = AB5500_BANK_LED, | ||
168 | .nranges = 1, | ||
169 | .range = (struct ab5500_reg_range[]) { | ||
170 | { | ||
171 | .first = 0x00, | ||
172 | .last = 0x0C, | ||
173 | .perm = AB5500_PERM_RW, | ||
174 | }, | ||
175 | }, | ||
176 | }, | ||
177 | }, | ||
178 | }, | ||
179 | [AB5500_DEVID_VIDEO] = { | ||
180 | .nbanks = 1, | ||
181 | .bank = (struct ab5500_i2c_ranges []) { | ||
182 | { | ||
183 | .bankid = AB5500_BANK_VDENC, | ||
184 | .nranges = 12, | ||
185 | .range = (struct ab5500_reg_range[]) { | ||
186 | { | ||
187 | .first = 0x00, | ||
188 | .last = 0x08, | ||
189 | .perm = AB5500_PERM_RW, | ||
190 | }, | ||
191 | { | ||
192 | .first = 0x09, | ||
193 | .last = 0x09, | ||
194 | .perm = AB5500_PERM_RO, | ||
195 | }, | ||
196 | { | ||
197 | .first = 0x0A, | ||
198 | .last = 0x12, | ||
199 | .perm = AB5500_PERM_RW, | ||
200 | }, | ||
201 | { | ||
202 | .first = 0x15, | ||
203 | .last = 0x19, | ||
204 | .perm = AB5500_PERM_RW, | ||
205 | }, | ||
206 | { | ||
207 | .first = 0x1B, | ||
208 | .last = 0x21, | ||
209 | .perm = AB5500_PERM_RW, | ||
210 | }, | ||
211 | { | ||
212 | .first = 0x27, | ||
213 | .last = 0x2C, | ||
214 | .perm = AB5500_PERM_RW, | ||
215 | }, | ||
216 | { | ||
217 | .first = 0x41, | ||
218 | .last = 0x41, | ||
219 | .perm = AB5500_PERM_RW, | ||
220 | }, | ||
221 | { | ||
222 | .first = 0x45, | ||
223 | .last = 0x5B, | ||
224 | .perm = AB5500_PERM_RW, | ||
225 | }, | ||
226 | { | ||
227 | .first = 0x5D, | ||
228 | .last = 0x5D, | ||
229 | .perm = AB5500_PERM_RW, | ||
230 | }, | ||
231 | { | ||
232 | .first = 0x69, | ||
233 | .last = 0x69, | ||
234 | .perm = AB5500_PERM_RW, | ||
235 | }, | ||
236 | { | ||
237 | .first = 0x6C, | ||
238 | .last = 0x6D, | ||
239 | .perm = AB5500_PERM_RW, | ||
240 | }, | ||
241 | { | ||
242 | .first = 0x80, | ||
243 | .last = 0x81, | ||
244 | .perm = AB5500_PERM_RW, | ||
245 | }, | ||
246 | }, | ||
247 | }, | ||
248 | }, | ||
249 | }, | ||
250 | [AB5500_DEVID_REGULATORS] = { | ||
251 | .nbanks = 2, | ||
252 | .bank = (struct ab5500_i2c_ranges []) { | ||
253 | { | ||
254 | .bankid = AB5500_BANK_STARTUP, | ||
255 | .nranges = 12, | ||
256 | .range = (struct ab5500_reg_range[]) { | ||
257 | { | ||
258 | .first = 0x00, | ||
259 | .last = 0x01, | ||
260 | .perm = AB5500_PERM_RW, | ||
261 | }, | ||
262 | { | ||
263 | .first = 0x1F, | ||
264 | .last = 0x1F, | ||
265 | .perm = AB5500_PERM_RW, | ||
266 | }, | ||
267 | { | ||
268 | .first = 0x2E, | ||
269 | .last = 0x2E, | ||
270 | .perm = AB5500_PERM_RO, | ||
271 | }, | ||
272 | { | ||
273 | .first = 0x2F, | ||
274 | .last = 0x30, | ||
275 | .perm = AB5500_PERM_RW, | ||
276 | }, | ||
277 | { | ||
278 | .first = 0x50, | ||
279 | .last = 0x51, | ||
280 | .perm = AB5500_PERM_RW, | ||
281 | }, | ||
282 | { | ||
283 | .first = 0x60, | ||
284 | .last = 0x61, | ||
285 | .perm = AB5500_PERM_RW, | ||
286 | }, | ||
287 | { | ||
288 | .first = 0x66, | ||
289 | .last = 0x8A, | ||
290 | .perm = AB5500_PERM_RW, | ||
291 | }, | ||
292 | { | ||
293 | .first = 0x8C, | ||
294 | .last = 0x96, | ||
295 | .perm = AB5500_PERM_RW, | ||
296 | }, | ||
297 | { | ||
298 | .first = 0xAA, | ||
299 | .last = 0xB4, | ||
300 | .perm = AB5500_PERM_RW, | ||
301 | }, | ||
302 | { | ||
303 | .first = 0xB7, | ||
304 | .last = 0xBF, | ||
305 | .perm = AB5500_PERM_RW, | ||
306 | }, | ||
307 | { | ||
308 | .first = 0xC1, | ||
309 | .last = 0xCA, | ||
310 | .perm = AB5500_PERM_RW, | ||
311 | }, | ||
312 | { | ||
313 | .first = 0xD3, | ||
314 | .last = 0xE0, | ||
315 | .perm = AB5500_PERM_RW, | ||
316 | }, | ||
317 | }, | ||
318 | }, | ||
319 | { | ||
320 | .bankid = AB5500_BANK_SIM_USBSIM, | ||
321 | .nranges = 1, | ||
322 | .range = (struct ab5500_reg_range[]) { | ||
323 | { | ||
324 | .first = 0x13, | ||
325 | .last = 0x19, | ||
326 | .perm = AB5500_PERM_RW, | ||
327 | }, | ||
328 | }, | ||
329 | }, | ||
330 | }, | ||
331 | }, | ||
332 | [AB5500_DEVID_SIM] = { | ||
333 | .nbanks = 1, | ||
334 | .bank = (struct ab5500_i2c_ranges []) { | ||
335 | { | ||
336 | .bankid = AB5500_BANK_SIM_USBSIM, | ||
337 | .nranges = 1, | ||
338 | .range = (struct ab5500_reg_range[]) { | ||
339 | { | ||
340 | .first = 0x13, | ||
341 | .last = 0x19, | ||
342 | .perm = AB5500_PERM_RW, | ||
343 | }, | ||
344 | }, | ||
345 | }, | ||
346 | }, | ||
347 | }, | ||
348 | [AB5500_DEVID_RTC] = { | ||
349 | .nbanks = 1, | ||
350 | .bank = (struct ab5500_i2c_ranges []) { | ||
351 | { | ||
352 | .bankid = AB5500_BANK_RTC, | ||
353 | .nranges = 2, | ||
354 | .range = (struct ab5500_reg_range[]) { | ||
355 | { | ||
356 | .first = 0x00, | ||
357 | .last = 0x04, | ||
358 | .perm = AB5500_PERM_RW, | ||
359 | }, | ||
360 | { | ||
361 | .first = 0x06, | ||
362 | .last = 0x0C, | ||
363 | .perm = AB5500_PERM_RW, | ||
364 | }, | ||
365 | }, | ||
366 | }, | ||
367 | }, | ||
368 | }, | ||
369 | [AB5500_DEVID_CHARGER] = { | ||
370 | .nbanks = 1, | ||
371 | .bank = (struct ab5500_i2c_ranges []) { | ||
372 | { | ||
373 | .bankid = AB5500_BANK_CHG, | ||
374 | .nranges = 2, | ||
375 | .range = (struct ab5500_reg_range[]) { | ||
376 | { | ||
377 | .first = 0x11, | ||
378 | .last = 0x11, | ||
379 | .perm = AB5500_PERM_RO, | ||
380 | }, | ||
381 | { | ||
382 | .first = 0x12, | ||
383 | .last = 0x1B, | ||
384 | .perm = AB5500_PERM_RW, | ||
385 | }, | ||
386 | }, | ||
387 | }, | ||
388 | }, | ||
389 | }, | ||
390 | [AB5500_DEVID_FUELGAUGE] = { | ||
391 | .nbanks = 1, | ||
392 | .bank = (struct ab5500_i2c_ranges []) { | ||
393 | { | ||
394 | .bankid = AB5500_BANK_FG_BATTCOM_ACC, | ||
395 | .nranges = 2, | ||
396 | .range = (struct ab5500_reg_range[]) { | ||
397 | { | ||
398 | .first = 0x00, | ||
399 | .last = 0x0B, | ||
400 | .perm = AB5500_PERM_RO, | ||
401 | }, | ||
402 | { | ||
403 | .first = 0x0C, | ||
404 | .last = 0x10, | ||
405 | .perm = AB5500_PERM_RW, | ||
406 | }, | ||
407 | }, | ||
408 | }, | ||
409 | }, | ||
410 | }, | ||
411 | [AB5500_DEVID_VIBRATOR] = { | ||
412 | .nbanks = 1, | ||
413 | .bank = (struct ab5500_i2c_ranges []) { | ||
414 | { | ||
415 | .bankid = AB5500_BANK_VIBRA, | ||
416 | .nranges = 2, | ||
417 | .range = (struct ab5500_reg_range[]) { | ||
418 | { | ||
419 | .first = 0x10, | ||
420 | .last = 0x13, | ||
421 | .perm = AB5500_PERM_RW, | ||
422 | }, | ||
423 | { | ||
424 | .first = 0xFE, | ||
425 | .last = 0xFE, | ||
426 | .perm = AB5500_PERM_RW, | ||
427 | }, | ||
428 | }, | ||
429 | }, | ||
430 | }, | ||
431 | }, | ||
432 | [AB5500_DEVID_CODEC] = { | ||
433 | .nbanks = 1, | ||
434 | .bank = (struct ab5500_i2c_ranges []) { | ||
435 | { | ||
436 | .bankid = AB5500_BANK_AUDIO_HEADSETUSB, | ||
437 | .nranges = 2, | ||
438 | .range = (struct ab5500_reg_range[]) { | ||
439 | { | ||
440 | .first = 0x00, | ||
441 | .last = 0x48, | ||
442 | .perm = AB5500_PERM_RW, | ||
443 | }, | ||
444 | { | ||
445 | .first = 0xEB, | ||
446 | .last = 0xFB, | ||
447 | .perm = AB5500_PERM_RW, | ||
448 | }, | ||
449 | }, | ||
450 | }, | ||
451 | }, | ||
452 | }, | ||
453 | [AB5500_DEVID_POWER] = { | ||
454 | .nbanks = 2, | ||
455 | .bank = (struct ab5500_i2c_ranges []) { | ||
456 | { | ||
457 | .bankid = AB5500_BANK_STARTUP, | ||
458 | .nranges = 1, | ||
459 | .range = (struct ab5500_reg_range[]) { | ||
460 | { | ||
461 | .first = 0x30, | ||
462 | .last = 0x30, | ||
463 | .perm = AB5500_PERM_RW, | ||
464 | }, | ||
465 | }, | ||
466 | }, | ||
467 | { | ||
468 | .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, | ||
469 | .nranges = 1, | ||
470 | .range = (struct ab5500_reg_range[]) { | ||
471 | { | ||
472 | .first = 0x01, | ||
473 | .last = 0x01, | ||
474 | .perm = AB5500_PERM_RW, | ||
475 | }, | ||
476 | }, | ||
477 | }, | ||
478 | }, | ||
479 | }, | ||
480 | }; | ||
481 | |||
482 | #define AB5500_IRQ(bank, bit) ((bank) * 8 + (bit)) | ||
483 | |||
484 | /* I appologize for the resource names beeing a mix of upper case | ||
485 | * and lower case but I want them to be exact as the documentation */ | ||
486 | static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = { | ||
487 | [AB5500_DEVID_LEDS] = { | ||
488 | .name = "ab5500-leds", | ||
489 | .id = AB5500_DEVID_LEDS, | ||
490 | }, | ||
491 | [AB5500_DEVID_POWER] = { | ||
492 | .name = "ab5500-power", | ||
493 | .id = AB5500_DEVID_POWER, | ||
494 | }, | ||
495 | [AB5500_DEVID_REGULATORS] = { | ||
496 | .name = "ab5500-regulator", | ||
497 | .id = AB5500_DEVID_REGULATORS, | ||
498 | }, | ||
499 | [AB5500_DEVID_SIM] = { | ||
500 | .name = "ab5500-sim", | ||
501 | .id = AB5500_DEVID_SIM, | ||
502 | .num_resources = 1, | ||
503 | .resources = (struct resource[]) { | ||
504 | { | ||
505 | .name = "SIMOFF", | ||
506 | .flags = IORESOURCE_IRQ, | ||
507 | .start = AB5500_IRQ(2, 0), /*rising*/ | ||
508 | .end = AB5500_IRQ(2, 1), /*falling*/ | ||
509 | }, | ||
510 | }, | ||
511 | }, | ||
512 | [AB5500_DEVID_RTC] = { | ||
513 | .name = "ab5500-rtc", | ||
514 | .id = AB5500_DEVID_RTC, | ||
515 | .num_resources = 1, | ||
516 | .resources = (struct resource[]) { | ||
517 | { | ||
518 | .name = "RTC_Alarm", | ||
519 | .flags = IORESOURCE_IRQ, | ||
520 | .start = AB5500_IRQ(1, 7), | ||
521 | .end = AB5500_IRQ(1, 7), | ||
522 | } | ||
523 | }, | ||
524 | }, | ||
525 | [AB5500_DEVID_CHARGER] = { | ||
526 | .name = "ab5500-charger", | ||
527 | .id = AB5500_DEVID_CHARGER, | ||
528 | }, | ||
529 | [AB5500_DEVID_ADC] = { | ||
530 | .name = "ab5500-adc", | ||
531 | .id = AB5500_DEVID_ADC, | ||
532 | .num_resources = 10, | ||
533 | .resources = (struct resource[]) { | ||
534 | { | ||
535 | .name = "TRIGGER-0", | ||
536 | .flags = IORESOURCE_IRQ, | ||
537 | .start = AB5500_IRQ(0, 0), | ||
538 | .end = AB5500_IRQ(0, 0), | ||
539 | }, | ||
540 | { | ||
541 | .name = "TRIGGER-1", | ||
542 | .flags = IORESOURCE_IRQ, | ||
543 | .start = AB5500_IRQ(0, 1), | ||
544 | .end = AB5500_IRQ(0, 1), | ||
545 | }, | ||
546 | { | ||
547 | .name = "TRIGGER-2", | ||
548 | .flags = IORESOURCE_IRQ, | ||
549 | .start = AB5500_IRQ(0, 2), | ||
550 | .end = AB5500_IRQ(0, 2), | ||
551 | }, | ||
552 | { | ||
553 | .name = "TRIGGER-3", | ||
554 | .flags = IORESOURCE_IRQ, | ||
555 | .start = AB5500_IRQ(0, 3), | ||
556 | .end = AB5500_IRQ(0, 3), | ||
557 | }, | ||
558 | { | ||
559 | .name = "TRIGGER-4", | ||
560 | .flags = IORESOURCE_IRQ, | ||
561 | .start = AB5500_IRQ(0, 4), | ||
562 | .end = AB5500_IRQ(0, 4), | ||
563 | }, | ||
564 | { | ||
565 | .name = "TRIGGER-5", | ||
566 | .flags = IORESOURCE_IRQ, | ||
567 | .start = AB5500_IRQ(0, 5), | ||
568 | .end = AB5500_IRQ(0, 5), | ||
569 | }, | ||
570 | { | ||
571 | .name = "TRIGGER-6", | ||
572 | .flags = IORESOURCE_IRQ, | ||
573 | .start = AB5500_IRQ(0, 6), | ||
574 | .end = AB5500_IRQ(0, 6), | ||
575 | }, | ||
576 | { | ||
577 | .name = "TRIGGER-7", | ||
578 | .flags = IORESOURCE_IRQ, | ||
579 | .start = AB5500_IRQ(0, 7), | ||
580 | .end = AB5500_IRQ(0, 7), | ||
581 | }, | ||
582 | { | ||
583 | .name = "TRIGGER-VBAT", | ||
584 | .flags = IORESOURCE_IRQ, | ||
585 | .start = AB5500_IRQ(0, 8), | ||
586 | .end = AB5500_IRQ(0, 8), | ||
587 | }, | ||
588 | { | ||
589 | .name = "TRIGGER-VBAT-TXON", | ||
590 | .flags = IORESOURCE_IRQ, | ||
591 | .start = AB5500_IRQ(0, 9), | ||
592 | .end = AB5500_IRQ(0, 9), | ||
593 | }, | ||
594 | }, | ||
595 | }, | ||
596 | [AB5500_DEVID_FUELGAUGE] = { | ||
597 | .name = "ab5500-fuelgauge", | ||
598 | .id = AB5500_DEVID_FUELGAUGE, | ||
599 | .num_resources = 6, | ||
600 | .resources = (struct resource[]) { | ||
601 | { | ||
602 | .name = "Batt_attach", | ||
603 | .flags = IORESOURCE_IRQ, | ||
604 | .start = AB5500_IRQ(7, 5), | ||
605 | .end = AB5500_IRQ(7, 5), | ||
606 | }, | ||
607 | { | ||
608 | .name = "Batt_removal", | ||
609 | .flags = IORESOURCE_IRQ, | ||
610 | .start = AB5500_IRQ(7, 6), | ||
611 | .end = AB5500_IRQ(7, 6), | ||
612 | }, | ||
613 | { | ||
614 | .name = "UART_framing", | ||
615 | .flags = IORESOURCE_IRQ, | ||
616 | .start = AB5500_IRQ(7, 7), | ||
617 | .end = AB5500_IRQ(7, 7), | ||
618 | }, | ||
619 | { | ||
620 | .name = "UART_overrun", | ||
621 | .flags = IORESOURCE_IRQ, | ||
622 | .start = AB5500_IRQ(8, 0), | ||
623 | .end = AB5500_IRQ(8, 0), | ||
624 | }, | ||
625 | { | ||
626 | .name = "UART_Rdy_RX", | ||
627 | .flags = IORESOURCE_IRQ, | ||
628 | .start = AB5500_IRQ(8, 1), | ||
629 | .end = AB5500_IRQ(8, 1), | ||
630 | }, | ||
631 | { | ||
632 | .name = "UART_Rdy_TX", | ||
633 | .flags = IORESOURCE_IRQ, | ||
634 | .start = AB5500_IRQ(8, 2), | ||
635 | .end = AB5500_IRQ(8, 2), | ||
636 | }, | ||
637 | }, | ||
638 | }, | ||
639 | [AB5500_DEVID_VIBRATOR] = { | ||
640 | .name = "ab5500-vibrator", | ||
641 | .id = AB5500_DEVID_VIBRATOR, | ||
642 | }, | ||
643 | [AB5500_DEVID_CODEC] = { | ||
644 | .name = "ab5500-codec", | ||
645 | .id = AB5500_DEVID_CODEC, | ||
646 | .num_resources = 3, | ||
647 | .resources = (struct resource[]) { | ||
648 | { | ||
649 | .name = "audio_spkr1_ovc", | ||
650 | .flags = IORESOURCE_IRQ, | ||
651 | .start = AB5500_IRQ(9, 5), | ||
652 | .end = AB5500_IRQ(9, 5), | ||
653 | }, | ||
654 | { | ||
655 | .name = "audio_plllocked", | ||
656 | .flags = IORESOURCE_IRQ, | ||
657 | .start = AB5500_IRQ(9, 6), | ||
658 | .end = AB5500_IRQ(9, 6), | ||
659 | }, | ||
660 | { | ||
661 | .name = "audio_spkr2_ovc", | ||
662 | .flags = IORESOURCE_IRQ, | ||
663 | .start = AB5500_IRQ(17, 4), | ||
664 | .end = AB5500_IRQ(17, 4), | ||
665 | }, | ||
666 | }, | ||
667 | }, | ||
668 | [AB5500_DEVID_USB] = { | ||
669 | .name = "ab5500-usb", | ||
670 | .id = AB5500_DEVID_USB, | ||
671 | .num_resources = 36, | ||
672 | .resources = (struct resource[]) { | ||
673 | { | ||
674 | .name = "Link_Update", | ||
675 | .flags = IORESOURCE_IRQ, | ||
676 | .start = AB5500_IRQ(22, 1), | ||
677 | .end = AB5500_IRQ(22, 1), | ||
678 | }, | ||
679 | { | ||
680 | .name = "DCIO", | ||
681 | .flags = IORESOURCE_IRQ, | ||
682 | .start = AB5500_IRQ(8, 3), | ||
683 | .end = AB5500_IRQ(8, 4), | ||
684 | }, | ||
685 | { | ||
686 | .name = "VBUS_R", | ||
687 | .flags = IORESOURCE_IRQ, | ||
688 | .start = AB5500_IRQ(8, 5), | ||
689 | .end = AB5500_IRQ(8, 5), | ||
690 | }, | ||
691 | { | ||
692 | .name = "VBUS_F", | ||
693 | .flags = IORESOURCE_IRQ, | ||
694 | .start = AB5500_IRQ(8, 6), | ||
695 | .end = AB5500_IRQ(8, 6), | ||
696 | }, | ||
697 | { | ||
698 | .name = "CHGstate_10_PCVBUSchg", | ||
699 | .flags = IORESOURCE_IRQ, | ||
700 | .start = AB5500_IRQ(8, 7), | ||
701 | .end = AB5500_IRQ(8, 7), | ||
702 | }, | ||
703 | { | ||
704 | .name = "DCIOreverse_ovc", | ||
705 | .flags = IORESOURCE_IRQ, | ||
706 | .start = AB5500_IRQ(9, 0), | ||
707 | .end = AB5500_IRQ(9, 0), | ||
708 | }, | ||
709 | { | ||
710 | .name = "USBCharDetDone", | ||
711 | .flags = IORESOURCE_IRQ, | ||
712 | .start = AB5500_IRQ(9, 1), | ||
713 | .end = AB5500_IRQ(9, 1), | ||
714 | }, | ||
715 | { | ||
716 | .name = "DCIO_no_limit", | ||
717 | .flags = IORESOURCE_IRQ, | ||
718 | .start = AB5500_IRQ(9, 2), | ||
719 | .end = AB5500_IRQ(9, 2), | ||
720 | }, | ||
721 | { | ||
722 | .name = "USB_suspend", | ||
723 | .flags = IORESOURCE_IRQ, | ||
724 | .start = AB5500_IRQ(9, 3), | ||
725 | .end = AB5500_IRQ(9, 3), | ||
726 | }, | ||
727 | { | ||
728 | .name = "DCIOreverse_fwdcurrent", | ||
729 | .flags = IORESOURCE_IRQ, | ||
730 | .start = AB5500_IRQ(9, 4), | ||
731 | .end = AB5500_IRQ(9, 4), | ||
732 | }, | ||
733 | { | ||
734 | .name = "Vbus_Imeasmax_change", | ||
735 | .flags = IORESOURCE_IRQ, | ||
736 | .start = AB5500_IRQ(9, 5), | ||
737 | .end = AB5500_IRQ(9, 6), | ||
738 | }, | ||
739 | { | ||
740 | .name = "OVV", | ||
741 | .flags = IORESOURCE_IRQ, | ||
742 | .start = AB5500_IRQ(14, 5), | ||
743 | .end = AB5500_IRQ(14, 5), | ||
744 | }, | ||
745 | { | ||
746 | .name = "USBcharging_NOTok", | ||
747 | .flags = IORESOURCE_IRQ, | ||
748 | .start = AB5500_IRQ(15, 3), | ||
749 | .end = AB5500_IRQ(15, 3), | ||
750 | }, | ||
751 | { | ||
752 | .name = "usb_adp_sensoroff", | ||
753 | .flags = IORESOURCE_IRQ, | ||
754 | .start = AB5500_IRQ(15, 6), | ||
755 | .end = AB5500_IRQ(15, 6), | ||
756 | }, | ||
757 | { | ||
758 | .name = "usb_adp_probeplug", | ||
759 | .flags = IORESOURCE_IRQ, | ||
760 | .start = AB5500_IRQ(15, 7), | ||
761 | .end = AB5500_IRQ(15, 7), | ||
762 | }, | ||
763 | { | ||
764 | .name = "usb_adp_sinkerror", | ||
765 | .flags = IORESOURCE_IRQ, | ||
766 | .start = AB5500_IRQ(16, 0), | ||
767 | .end = AB5500_IRQ(16, 6), | ||
768 | }, | ||
769 | { | ||
770 | .name = "usb_adp_sourceerror", | ||
771 | .flags = IORESOURCE_IRQ, | ||
772 | .start = AB5500_IRQ(16, 1), | ||
773 | .end = AB5500_IRQ(16, 1), | ||
774 | }, | ||
775 | { | ||
776 | .name = "usb_idgnd_r", | ||
777 | .flags = IORESOURCE_IRQ, | ||
778 | .start = AB5500_IRQ(16, 2), | ||
779 | .end = AB5500_IRQ(16, 2), | ||
780 | }, | ||
781 | { | ||
782 | .name = "usb_idgnd_f", | ||
783 | .flags = IORESOURCE_IRQ, | ||
784 | .start = AB5500_IRQ(16, 3), | ||
785 | .end = AB5500_IRQ(16, 3), | ||
786 | }, | ||
787 | { | ||
788 | .name = "usb_iddetR1", | ||
789 | .flags = IORESOURCE_IRQ, | ||
790 | .start = AB5500_IRQ(16, 4), | ||
791 | .end = AB5500_IRQ(16, 5), | ||
792 | }, | ||
793 | { | ||
794 | .name = "usb_iddetR2", | ||
795 | .flags = IORESOURCE_IRQ, | ||
796 | .start = AB5500_IRQ(16, 6), | ||
797 | .end = AB5500_IRQ(16, 7), | ||
798 | }, | ||
799 | { | ||
800 | .name = "usb_iddetR3", | ||
801 | .flags = IORESOURCE_IRQ, | ||
802 | .start = AB5500_IRQ(17, 0), | ||
803 | .end = AB5500_IRQ(17, 1), | ||
804 | }, | ||
805 | { | ||
806 | .name = "usb_iddetR4", | ||
807 | .flags = IORESOURCE_IRQ, | ||
808 | .start = AB5500_IRQ(17, 2), | ||
809 | .end = AB5500_IRQ(17, 3), | ||
810 | }, | ||
811 | { | ||
812 | .name = "CharTempWindowOk", | ||
813 | .flags = IORESOURCE_IRQ, | ||
814 | .start = AB5500_IRQ(17, 7), | ||
815 | .end = AB5500_IRQ(18, 0), | ||
816 | }, | ||
817 | { | ||
818 | .name = "USB_SprDetect", | ||
819 | .flags = IORESOURCE_IRQ, | ||
820 | .start = AB5500_IRQ(18, 1), | ||
821 | .end = AB5500_IRQ(18, 1), | ||
822 | }, | ||
823 | { | ||
824 | .name = "usb_adp_probe_unplug", | ||
825 | .flags = IORESOURCE_IRQ, | ||
826 | .start = AB5500_IRQ(18, 2), | ||
827 | .end = AB5500_IRQ(18, 2), | ||
828 | }, | ||
829 | { | ||
830 | .name = "VBUSChDrop", | ||
831 | .flags = IORESOURCE_IRQ, | ||
832 | .start = AB5500_IRQ(18, 3), | ||
833 | .end = AB5500_IRQ(18, 4), | ||
834 | }, | ||
835 | { | ||
836 | .name = "dcio_char_rec_done", | ||
837 | .flags = IORESOURCE_IRQ, | ||
838 | .start = AB5500_IRQ(18, 5), | ||
839 | .end = AB5500_IRQ(18, 5), | ||
840 | }, | ||
841 | { | ||
842 | .name = "Charging_stopped_by_temp", | ||
843 | .flags = IORESOURCE_IRQ, | ||
844 | .start = AB5500_IRQ(18, 6), | ||
845 | .end = AB5500_IRQ(18, 6), | ||
846 | }, | ||
847 | { | ||
848 | .name = "CHGstate_11_SafeModeVBUS", | ||
849 | .flags = IORESOURCE_IRQ, | ||
850 | .start = AB5500_IRQ(21, 1), | ||
851 | .end = AB5500_IRQ(21, 2), | ||
852 | }, | ||
853 | { | ||
854 | .name = "CHGstate_12_comletedVBUS", | ||
855 | .flags = IORESOURCE_IRQ, | ||
856 | .start = AB5500_IRQ(21, 2), | ||
857 | .end = AB5500_IRQ(21, 2), | ||
858 | }, | ||
859 | { | ||
860 | .name = "CHGstate_13_completedVBUS", | ||
861 | .flags = IORESOURCE_IRQ, | ||
862 | .start = AB5500_IRQ(21, 3), | ||
863 | .end = AB5500_IRQ(21, 3), | ||
864 | }, | ||
865 | { | ||
866 | .name = "CHGstate_14_FullChgDCIO", | ||
867 | .flags = IORESOURCE_IRQ, | ||
868 | .start = AB5500_IRQ(21, 4), | ||
869 | .end = AB5500_IRQ(21, 4), | ||
870 | }, | ||
871 | { | ||
872 | .name = "CHGstate_15_SafeModeDCIO", | ||
873 | .flags = IORESOURCE_IRQ, | ||
874 | .start = AB5500_IRQ(21, 5), | ||
875 | .end = AB5500_IRQ(21, 5), | ||
876 | }, | ||
877 | { | ||
878 | .name = "CHGstate_16_OFFsuspendDCIO", | ||
879 | .flags = IORESOURCE_IRQ, | ||
880 | .start = AB5500_IRQ(21, 6), | ||
881 | .end = AB5500_IRQ(21, 6), | ||
882 | }, | ||
883 | { | ||
884 | .name = "CHGstate_17_completedDCIO", | ||
885 | .flags = IORESOURCE_IRQ, | ||
886 | .start = AB5500_IRQ(21, 7), | ||
887 | .end = AB5500_IRQ(21, 7), | ||
888 | }, | ||
889 | }, | ||
890 | }, | ||
891 | [AB5500_DEVID_OTP] = { | ||
892 | .name = "ab5500-otp", | ||
893 | .id = AB5500_DEVID_OTP, | ||
894 | }, | ||
895 | [AB5500_DEVID_VIDEO] = { | ||
896 | .name = "ab5500-video", | ||
897 | .id = AB5500_DEVID_VIDEO, | ||
898 | .num_resources = 1, | ||
899 | .resources = (struct resource[]) { | ||
900 | { | ||
901 | .name = "plugTVdet", | ||
902 | .flags = IORESOURCE_IRQ, | ||
903 | .start = AB5500_IRQ(22, 2), | ||
904 | .end = AB5500_IRQ(22, 2), | ||
905 | }, | ||
906 | }, | ||
907 | }, | ||
908 | [AB5500_DEVID_DBIECI] = { | ||
909 | .name = "ab5500-dbieci", | ||
910 | .id = AB5500_DEVID_DBIECI, | ||
911 | .num_resources = 10, | ||
912 | .resources = (struct resource[]) { | ||
913 | { | ||
914 | .name = "COLL", | ||
915 | .flags = IORESOURCE_IRQ, | ||
916 | .start = AB5500_IRQ(14, 0), | ||
917 | .end = AB5500_IRQ(14, 0), | ||
918 | }, | ||
919 | { | ||
920 | .name = "RESERR", | ||
921 | .flags = IORESOURCE_IRQ, | ||
922 | .start = AB5500_IRQ(14, 1), | ||
923 | .end = AB5500_IRQ(14, 1), | ||
924 | }, | ||
925 | { | ||
926 | .name = "FRAERR", | ||
927 | .flags = IORESOURCE_IRQ, | ||
928 | .start = AB5500_IRQ(14, 2), | ||
929 | .end = AB5500_IRQ(14, 2), | ||
930 | }, | ||
931 | { | ||
932 | .name = "COMERR", | ||
933 | .flags = IORESOURCE_IRQ, | ||
934 | .start = AB5500_IRQ(14, 3), | ||
935 | .end = AB5500_IRQ(14, 3), | ||
936 | }, | ||
937 | { | ||
938 | .name = "BSI_indicator", | ||
939 | .flags = IORESOURCE_IRQ, | ||
940 | .start = AB5500_IRQ(14, 4), | ||
941 | .end = AB5500_IRQ(14, 4), | ||
942 | }, | ||
943 | { | ||
944 | .name = "SPDSET", | ||
945 | .flags = IORESOURCE_IRQ, | ||
946 | .start = AB5500_IRQ(14, 6), | ||
947 | .end = AB5500_IRQ(14, 6), | ||
948 | }, | ||
949 | { | ||
950 | .name = "DSENT", | ||
951 | .flags = IORESOURCE_IRQ, | ||
952 | .start = AB5500_IRQ(14, 7), | ||
953 | .end = AB5500_IRQ(14, 7), | ||
954 | }, | ||
955 | { | ||
956 | .name = "DREC", | ||
957 | .flags = IORESOURCE_IRQ, | ||
958 | .start = AB5500_IRQ(15, 0), | ||
959 | .end = AB5500_IRQ(15, 0), | ||
960 | }, | ||
961 | { | ||
962 | .name = "ACCINT", | ||
963 | .flags = IORESOURCE_IRQ, | ||
964 | .start = AB5500_IRQ(15, 1), | ||
965 | .end = AB5500_IRQ(15, 1), | ||
966 | }, | ||
967 | { | ||
968 | .name = "NOPINT", | ||
969 | .flags = IORESOURCE_IRQ, | ||
970 | .start = AB5500_IRQ(15, 2), | ||
971 | .end = AB5500_IRQ(15, 2), | ||
972 | }, | ||
973 | }, | ||
974 | }, | ||
975 | [AB5500_DEVID_ONSWA] = { | ||
976 | .name = "ab5500-onswa", | ||
977 | .id = AB5500_DEVID_ONSWA, | ||
978 | .num_resources = 2, | ||
979 | .resources = (struct resource[]) { | ||
980 | { | ||
981 | .name = "ONSWAn_rising", | ||
982 | .flags = IORESOURCE_IRQ, | ||
983 | .start = AB5500_IRQ(1, 3), | ||
984 | .end = AB5500_IRQ(1, 3), | ||
985 | }, | ||
986 | { | ||
987 | .name = "ONSWAn_falling", | ||
988 | .flags = IORESOURCE_IRQ, | ||
989 | .start = AB5500_IRQ(1, 4), | ||
990 | .end = AB5500_IRQ(1, 4), | ||
991 | }, | ||
992 | }, | ||
993 | }, | ||
994 | }; | ||
995 | |||
996 | /* | ||
997 | * Functionality for getting/setting register values. | ||
998 | */ | ||
999 | int ab5500_get_register_interruptible_raw(struct ab5500 *ab, | ||
1000 | u8 bank, u8 reg, | ||
1001 | u8 *value) | ||
1002 | { | ||
1003 | int err; | ||
1004 | |||
1005 | if (bank >= AB5500_NUM_BANKS) | ||
1006 | return -EINVAL; | ||
1007 | |||
1008 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
1009 | if (err) | ||
1010 | return err; | ||
1011 | err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1); | ||
1012 | |||
1013 | mutex_unlock(&ab->access_mutex); | ||
1014 | return err; | ||
1015 | } | ||
1016 | |||
1017 | static int get_register_page_interruptible(struct ab5500 *ab, u8 bank, | ||
1018 | u8 first_reg, u8 *regvals, u8 numregs) | ||
1019 | { | ||
1020 | int err; | ||
1021 | |||
1022 | if (bank >= AB5500_NUM_BANKS) | ||
1023 | return -EINVAL; | ||
1024 | |||
1025 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
1026 | if (err) | ||
1027 | return err; | ||
1028 | |||
1029 | while (numregs) { | ||
1030 | /* The hardware limit for get page is 4 */ | ||
1031 | u8 curnum = min_t(u8, numregs, 4u); | ||
1032 | |||
1033 | err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, | ||
1034 | first_reg, regvals, curnum); | ||
1035 | if (err) | ||
1036 | goto out; | ||
1037 | |||
1038 | numregs -= curnum; | ||
1039 | first_reg += curnum; | ||
1040 | regvals += curnum; | ||
1041 | } | ||
1042 | |||
1043 | out: | ||
1044 | mutex_unlock(&ab->access_mutex); | ||
1045 | return err; | ||
1046 | } | ||
1047 | |||
1048 | int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, | ||
1049 | u8 reg, u8 bitmask, u8 bitvalues) | ||
1050 | { | ||
1051 | int err = 0; | ||
1052 | |||
1053 | if (bank >= AB5500_NUM_BANKS) | ||
1054 | return -EINVAL; | ||
1055 | |||
1056 | if (bitmask) { | ||
1057 | u8 buf; | ||
1058 | |||
1059 | err = mutex_lock_interruptible(&ab->access_mutex); | ||
1060 | if (err) | ||
1061 | return err; | ||
1062 | |||
1063 | if (bitmask == 0xFF) /* No need to read in this case. */ | ||
1064 | buf = bitvalues; | ||
1065 | else { /* Read and modify the register value. */ | ||
1066 | err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, | ||
1067 | reg, &buf, 1); | ||
1068 | if (err) | ||
1069 | return err; | ||
1070 | |||
1071 | buf = ((~bitmask & buf) | (bitmask & bitvalues)); | ||
1072 | } | ||
1073 | /* Write the new value. */ | ||
1074 | err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg, | ||
1075 | &buf, 1); | ||
1076 | |||
1077 | mutex_unlock(&ab->access_mutex); | ||
1078 | } | ||
1079 | return err; | ||
1080 | } | ||
1081 | |||
1082 | static int | ||
1083 | set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value) | ||
1084 | { | ||
1085 | return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, | ||
1086 | 0xff, value); | ||
1087 | } | ||
1088 | |||
1089 | /* | ||
1090 | * Read/write permission checking functions. | ||
1091 | */ | ||
1092 | static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank) | ||
1093 | { | ||
1094 | u8 i; | ||
1095 | |||
1096 | if (devid < AB5500_NUM_DEVICES) { | ||
1097 | for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) { | ||
1098 | if (ab5500_bank_ranges[devid].bank[i].bankid == bank) | ||
1099 | return &ab5500_bank_ranges[devid].bank[i]; | ||
1100 | } | ||
1101 | } | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | |||
1105 | static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) | ||
1106 | { | ||
1107 | u8 i; /* range loop index */ | ||
1108 | const struct ab5500_i2c_ranges *bankref; | ||
1109 | |||
1110 | bankref = get_bankref(devid, bank); | ||
1111 | if (bankref == NULL || last_reg < first_reg) | ||
1112 | return false; | ||
1113 | |||
1114 | for (i = 0; i < bankref->nranges; i++) { | ||
1115 | if (first_reg < bankref->range[i].first) | ||
1116 | break; | ||
1117 | if ((last_reg <= bankref->range[i].last) && | ||
1118 | (bankref->range[i].perm & AB5500_PERM_WR)) | ||
1119 | return true; | ||
1120 | } | ||
1121 | return false; | ||
1122 | } | ||
1123 | |||
1124 | static bool reg_write_allowed(u8 devid, u8 bank, u8 reg) | ||
1125 | { | ||
1126 | return page_write_allowed(devid, bank, reg, reg); | ||
1127 | } | ||
1128 | |||
1129 | static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg) | ||
1130 | { | ||
1131 | u8 i; | ||
1132 | const struct ab5500_i2c_ranges *bankref; | ||
1133 | |||
1134 | bankref = get_bankref(devid, bank); | ||
1135 | if (bankref == NULL || last_reg < first_reg) | ||
1136 | return false; | ||
1137 | |||
1138 | |||
1139 | /* Find the range (if it exists in the list) that includes first_reg. */ | ||
1140 | for (i = 0; i < bankref->nranges; i++) { | ||
1141 | if (first_reg < bankref->range[i].first) | ||
1142 | return false; | ||
1143 | if (first_reg <= bankref->range[i].last) | ||
1144 | break; | ||
1145 | } | ||
1146 | /* Make sure that the entire range up to and including last_reg is | ||
1147 | * readable. This may span several of the ranges in the list. | ||
1148 | */ | ||
1149 | while ((i < bankref->nranges) && | ||
1150 | (bankref->range[i].perm & AB5500_PERM_RD)) { | ||
1151 | if (last_reg <= bankref->range[i].last) | ||
1152 | return true; | ||
1153 | if ((++i >= bankref->nranges) || | ||
1154 | (bankref->range[i].first != | ||
1155 | (bankref->range[i - 1].last + 1))) { | ||
1156 | break; | ||
1157 | } | ||
1158 | } | ||
1159 | return false; | ||
1160 | } | ||
1161 | |||
1162 | static bool reg_read_allowed(u8 devid, u8 bank, u8 reg) | ||
1163 | { | ||
1164 | return page_read_allowed(devid, bank, reg, reg); | ||
1165 | } | ||
1166 | |||
1167 | |||
1168 | /* | ||
1169 | * The exported register access functionality. | ||
1170 | */ | ||
1171 | static int ab5500_get_chip_id(struct device *dev) | ||
1172 | { | ||
1173 | struct ab5500 *ab = dev_get_drvdata(dev->parent); | ||
1174 | |||
1175 | return (int)ab->chip_id; | ||
1176 | } | ||
1177 | |||
1178 | static int ab5500_mask_and_set_register_interruptible(struct device *dev, | ||
1179 | u8 bank, u8 reg, u8 bitmask, u8 bitvalues) | ||
1180 | { | ||
1181 | struct ab5500 *ab; | ||
1182 | struct platform_device *pdev = to_platform_device(dev); | ||
1183 | |||
1184 | if ((AB5500_NUM_BANKS <= bank) || | ||
1185 | !reg_write_allowed(pdev->id, bank, reg)) | ||
1186 | return -EINVAL; | ||
1187 | |||
1188 | ab = dev_get_drvdata(dev->parent); | ||
1189 | return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg, | ||
1190 | bitmask, bitvalues); | ||
1191 | } | ||
1192 | |||
1193 | static int ab5500_set_register_interruptible(struct device *dev, u8 bank, | ||
1194 | u8 reg, u8 value) | ||
1195 | { | ||
1196 | return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF, | ||
1197 | value); | ||
1198 | } | ||
1199 | |||
1200 | static int ab5500_get_register_interruptible(struct device *dev, u8 bank, | ||
1201 | u8 reg, u8 *value) | ||
1202 | { | ||
1203 | struct ab5500 *ab; | ||
1204 | struct platform_device *pdev = to_platform_device(dev); | ||
1205 | |||
1206 | if ((AB5500_NUM_BANKS <= bank) || | ||
1207 | !reg_read_allowed(pdev->id, bank, reg)) | ||
1208 | return -EINVAL; | ||
1209 | |||
1210 | ab = dev_get_drvdata(dev->parent); | ||
1211 | return ab5500_get_register_interruptible_raw(ab, bank, reg, value); | ||
1212 | } | ||
1213 | |||
1214 | static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank, | ||
1215 | u8 first_reg, u8 *regvals, u8 numregs) | ||
1216 | { | ||
1217 | struct ab5500 *ab; | ||
1218 | struct platform_device *pdev = to_platform_device(dev); | ||
1219 | |||
1220 | if ((AB5500_NUM_BANKS <= bank) || | ||
1221 | !page_read_allowed(pdev->id, bank, | ||
1222 | first_reg, (first_reg + numregs - 1))) | ||
1223 | return -EINVAL; | ||
1224 | |||
1225 | ab = dev_get_drvdata(dev->parent); | ||
1226 | return get_register_page_interruptible(ab, bank, first_reg, regvals, | ||
1227 | numregs); | ||
1228 | } | ||
1229 | |||
1230 | static int | ||
1231 | ab5500_event_registers_startup_state_get(struct device *dev, u8 *event) | ||
1232 | { | ||
1233 | struct ab5500 *ab; | ||
1234 | |||
1235 | ab = dev_get_drvdata(dev->parent); | ||
1236 | if (!ab->startup_events_read) | ||
1237 | return -EAGAIN; /* Try again later */ | ||
1238 | |||
1239 | memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG); | ||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | static struct abx500_ops ab5500_ops = { | ||
1244 | .get_chip_id = ab5500_get_chip_id, | ||
1245 | .get_register = ab5500_get_register_interruptible, | ||
1246 | .set_register = ab5500_set_register_interruptible, | ||
1247 | .get_register_page = ab5500_get_register_page_interruptible, | ||
1248 | .set_register_page = NULL, | ||
1249 | .mask_and_set_register = ab5500_mask_and_set_register_interruptible, | ||
1250 | .event_registers_startup_state_get = | ||
1251 | ab5500_event_registers_startup_state_get, | ||
1252 | .startup_irq_enabled = NULL, | ||
1253 | }; | ||
1254 | |||
1255 | /* | ||
1256 | * ab5500_setup : Basic set-up, datastructure creation/destruction | ||
1257 | * and I2C interface.This sets up a default config | ||
1258 | * in the AB5500 chip so that it will work as expected. | ||
1259 | * @ab : Pointer to ab5500 structure | ||
1260 | * @settings : Pointer to struct abx500_init_settings | ||
1261 | * @size : Size of init data | ||
1262 | */ | ||
1263 | static int __init ab5500_setup(struct ab5500 *ab, | ||
1264 | struct abx500_init_settings *settings, unsigned int size) | ||
1265 | { | ||
1266 | int err = 0; | ||
1267 | int i; | ||
1268 | |||
1269 | for (i = 0; i < size; i++) { | ||
1270 | err = ab5500_mask_and_set_register_interruptible_raw(ab, | ||
1271 | settings[i].bank, | ||
1272 | settings[i].reg, | ||
1273 | 0xFF, settings[i].setting); | ||
1274 | if (err) | ||
1275 | goto exit_no_setup; | ||
1276 | |||
1277 | /* If event mask register update the event mask in ab5500 */ | ||
1278 | if ((settings[i].bank == AB5500_BANK_IT) && | ||
1279 | (AB5500_MASK_BASE <= settings[i].reg) && | ||
1280 | (settings[i].reg <= AB5500_MASK_END)) { | ||
1281 | ab->mask[settings[i].reg - AB5500_MASK_BASE] = | ||
1282 | settings[i].setting; | ||
1283 | } | ||
1284 | } | ||
1285 | exit_no_setup: | ||
1286 | return err; | ||
1287 | } | ||
1288 | |||
1289 | struct ab_family_id { | ||
1290 | u8 id; | ||
1291 | char *name; | ||
1292 | }; | ||
1293 | |||
1294 | static const struct ab_family_id ids[] __initdata = { | ||
1295 | /* AB5500 */ | ||
1296 | { | ||
1297 | .id = AB5500_1_0, | ||
1298 | .name = "1.0" | ||
1299 | }, | ||
1300 | { | ||
1301 | .id = AB5500_1_1, | ||
1302 | .name = "1.1" | ||
1303 | }, | ||
1304 | /* Terminator */ | ||
1305 | { | ||
1306 | .id = 0x00, | ||
1307 | } | ||
1308 | }; | ||
1309 | |||
1310 | static int __init ab5500_probe(struct platform_device *pdev) | ||
1311 | { | ||
1312 | struct ab5500 *ab; | ||
1313 | struct ab5500_platform_data *ab5500_plf_data = | ||
1314 | pdev->dev.platform_data; | ||
1315 | int err; | ||
1316 | int i; | ||
1317 | |||
1318 | ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL); | ||
1319 | if (!ab) { | ||
1320 | dev_err(&pdev->dev, | ||
1321 | "could not allocate ab5500 device\n"); | ||
1322 | return -ENOMEM; | ||
1323 | } | ||
1324 | |||
1325 | /* Initialize data structure */ | ||
1326 | mutex_init(&ab->access_mutex); | ||
1327 | mutex_init(&ab->irq_lock); | ||
1328 | ab->dev = &pdev->dev; | ||
1329 | |||
1330 | platform_set_drvdata(pdev, ab); | ||
1331 | |||
1332 | /* Read chip ID register */ | ||
1333 | err = ab5500_get_register_interruptible_raw(ab, | ||
1334 | AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, | ||
1335 | AB5500_CHIP_ID, &ab->chip_id); | ||
1336 | if (err) { | ||
1337 | dev_err(&pdev->dev, "could not communicate with the analog " | ||
1338 | "baseband chip\n"); | ||
1339 | goto exit_no_detect; | ||
1340 | } | ||
1341 | |||
1342 | for (i = 0; ids[i].id != 0x0; i++) { | ||
1343 | if (ids[i].id == ab->chip_id) { | ||
1344 | snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1, | ||
1345 | "AB5500 %s", ids[i].name); | ||
1346 | break; | ||
1347 | } | ||
1348 | } | ||
1349 | if (ids[i].id == 0x0) { | ||
1350 | dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n", | ||
1351 | ab->chip_id); | ||
1352 | dev_err(&pdev->dev, "driver not started!\n"); | ||
1353 | goto exit_no_detect; | ||
1354 | } | ||
1355 | |||
1356 | /* Clear and mask all interrupts */ | ||
1357 | for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) { | ||
1358 | u8 latchreg = AB5500_IT_LATCH0_REG + i; | ||
1359 | u8 maskreg = AB5500_IT_MASK0_REG + i; | ||
1360 | u8 val; | ||
1361 | |||
1362 | ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT, | ||
1363 | latchreg, &val); | ||
1364 | set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff); | ||
1365 | ab->mask[i] = ab->oldmask[i] = 0xff; | ||
1366 | } | ||
1367 | |||
1368 | err = abx500_register_ops(&pdev->dev, &ab5500_ops); | ||
1369 | if (err) { | ||
1370 | dev_err(&pdev->dev, "ab5500_register ops error\n"); | ||
1371 | goto exit_no_detect; | ||
1372 | } | ||
1373 | |||
1374 | /* Set up and register the platform devices. */ | ||
1375 | for (i = 0; i < AB5500_NUM_DEVICES; i++) { | ||
1376 | ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i]; | ||
1377 | ab5500_devs[i].pdata_size = | ||
1378 | sizeof(ab5500_plf_data->dev_data[i]); | ||
1379 | } | ||
1380 | |||
1381 | err = mfd_add_devices(&pdev->dev, 0, ab5500_devs, | ||
1382 | ARRAY_SIZE(ab5500_devs), NULL, | ||
1383 | ab5500_plf_data->irq.base); | ||
1384 | if (err) { | ||
1385 | dev_err(&pdev->dev, "ab5500_mfd_add_device error\n"); | ||
1386 | goto exit_no_detect; | ||
1387 | } | ||
1388 | |||
1389 | err = ab5500_setup(ab, ab5500_plf_data->init_settings, | ||
1390 | ab5500_plf_data->init_settings_sz); | ||
1391 | if (err) { | ||
1392 | dev_err(&pdev->dev, "ab5500_setup error\n"); | ||
1393 | goto exit_no_detect; | ||
1394 | } | ||
1395 | |||
1396 | ab5500_setup_debugfs(ab); | ||
1397 | |||
1398 | dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]); | ||
1399 | return 0; | ||
1400 | |||
1401 | exit_no_detect: | ||
1402 | kfree(ab); | ||
1403 | return err; | ||
1404 | } | ||
1405 | |||
1406 | static int __exit ab5500_remove(struct platform_device *pdev) | ||
1407 | { | ||
1408 | struct ab5500 *ab = platform_get_drvdata(pdev); | ||
1409 | |||
1410 | ab5500_remove_debugfs(); | ||
1411 | mfd_remove_devices(&pdev->dev); | ||
1412 | kfree(ab); | ||
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | static struct platform_driver ab5500_driver = { | ||
1417 | .driver = { | ||
1418 | .name = "ab5500-core", | ||
1419 | .owner = THIS_MODULE, | ||
1420 | }, | ||
1421 | .remove = __exit_p(ab5500_remove), | ||
1422 | }; | ||
1423 | |||
1424 | static int __init ab5500_core_init(void) | ||
1425 | { | ||
1426 | return platform_driver_probe(&ab5500_driver, ab5500_probe); | ||
1427 | } | ||
1428 | |||
1429 | static void __exit ab5500_core_exit(void) | ||
1430 | { | ||
1431 | platform_driver_unregister(&ab5500_driver); | ||
1432 | } | ||
1433 | |||
1434 | subsys_initcall(ab5500_core_init); | ||
1435 | module_exit(ab5500_core_exit); | ||
1436 | |||
1437 | MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); | ||
1438 | MODULE_DESCRIPTION("AB5500 core driver"); | ||
1439 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c deleted file mode 100644 index 72006940937a..000000000000 --- a/drivers/mfd/ab5500-debugfs.c +++ /dev/null | |||
@@ -1,807 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Debugfs support for the AB5500 MFD driver | ||
5 | */ | ||
6 | |||
7 | #include <linux/module.h> | ||
8 | #include <linux/debugfs.h> | ||
9 | #include <linux/seq_file.h> | ||
10 | #include <linux/mfd/abx500.h> | ||
11 | #include <linux/mfd/abx500/ab5500.h> | ||
12 | #include <linux/uaccess.h> | ||
13 | |||
14 | #include "ab5500-core.h" | ||
15 | #include "ab5500-debugfs.h" | ||
16 | |||
17 | static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = { | ||
18 | [AB5500_BANK_LED] = { | ||
19 | .bankid = AB5500_BANK_LED, | ||
20 | .nranges = 1, | ||
21 | .range = (struct ab5500_reg_range[]) { | ||
22 | { | ||
23 | .first = 0x00, | ||
24 | .last = 0x0C, | ||
25 | .perm = AB5500_PERM_RW, | ||
26 | }, | ||
27 | }, | ||
28 | }, | ||
29 | [AB5500_BANK_ADC] = { | ||
30 | .bankid = AB5500_BANK_ADC, | ||
31 | .nranges = 6, | ||
32 | .range = (struct ab5500_reg_range[]) { | ||
33 | { | ||
34 | .first = 0x1F, | ||
35 | .last = 0x22, | ||
36 | .perm = AB5500_PERM_RO, | ||
37 | }, | ||
38 | { | ||
39 | .first = 0x23, | ||
40 | .last = 0x24, | ||
41 | .perm = AB5500_PERM_RW, | ||
42 | }, | ||
43 | { | ||
44 | .first = 0x26, | ||
45 | .last = 0x2D, | ||
46 | .perm = AB5500_PERM_RO, | ||
47 | }, | ||
48 | { | ||
49 | .first = 0x2F, | ||
50 | .last = 0x34, | ||
51 | .perm = AB5500_PERM_RW, | ||
52 | }, | ||
53 | { | ||
54 | .first = 0x37, | ||
55 | .last = 0x57, | ||
56 | .perm = AB5500_PERM_RW, | ||
57 | }, | ||
58 | { | ||
59 | .first = 0x58, | ||
60 | .last = 0x58, | ||
61 | .perm = AB5500_PERM_RO, | ||
62 | }, | ||
63 | }, | ||
64 | }, | ||
65 | [AB5500_BANK_RTC] = { | ||
66 | .bankid = AB5500_BANK_RTC, | ||
67 | .nranges = 2, | ||
68 | .range = (struct ab5500_reg_range[]) { | ||
69 | { | ||
70 | .first = 0x00, | ||
71 | .last = 0x04, | ||
72 | .perm = AB5500_PERM_RW, | ||
73 | }, | ||
74 | { | ||
75 | .first = 0x06, | ||
76 | .last = 0x0C, | ||
77 | .perm = AB5500_PERM_RW, | ||
78 | }, | ||
79 | }, | ||
80 | }, | ||
81 | [AB5500_BANK_STARTUP] = { | ||
82 | .bankid = AB5500_BANK_STARTUP, | ||
83 | .nranges = 12, | ||
84 | .range = (struct ab5500_reg_range[]) { | ||
85 | { | ||
86 | .first = 0x00, | ||
87 | .last = 0x01, | ||
88 | .perm = AB5500_PERM_RW, | ||
89 | }, | ||
90 | { | ||
91 | .first = 0x1F, | ||
92 | .last = 0x1F, | ||
93 | .perm = AB5500_PERM_RW, | ||
94 | }, | ||
95 | { | ||
96 | .first = 0x2E, | ||
97 | .last = 0x2E, | ||
98 | .perm = AB5500_PERM_RO, | ||
99 | }, | ||
100 | { | ||
101 | .first = 0x2F, | ||
102 | .last = 0x30, | ||
103 | .perm = AB5500_PERM_RW, | ||
104 | }, | ||
105 | { | ||
106 | .first = 0x50, | ||
107 | .last = 0x51, | ||
108 | .perm = AB5500_PERM_RW, | ||
109 | }, | ||
110 | { | ||
111 | .first = 0x60, | ||
112 | .last = 0x61, | ||
113 | .perm = AB5500_PERM_RW, | ||
114 | }, | ||
115 | { | ||
116 | .first = 0x66, | ||
117 | .last = 0x8A, | ||
118 | .perm = AB5500_PERM_RW, | ||
119 | }, | ||
120 | { | ||
121 | .first = 0x8C, | ||
122 | .last = 0x96, | ||
123 | .perm = AB5500_PERM_RW, | ||
124 | }, | ||
125 | { | ||
126 | .first = 0xAA, | ||
127 | .last = 0xB4, | ||
128 | .perm = AB5500_PERM_RW, | ||
129 | }, | ||
130 | { | ||
131 | .first = 0xB7, | ||
132 | .last = 0xBF, | ||
133 | .perm = AB5500_PERM_RW, | ||
134 | }, | ||
135 | { | ||
136 | .first = 0xC1, | ||
137 | .last = 0xCA, | ||
138 | .perm = AB5500_PERM_RW, | ||
139 | }, | ||
140 | { | ||
141 | .first = 0xD3, | ||
142 | .last = 0xE0, | ||
143 | .perm = AB5500_PERM_RW, | ||
144 | }, | ||
145 | }, | ||
146 | }, | ||
147 | [AB5500_BANK_DBI_ECI] = { | ||
148 | .bankid = AB5500_BANK_DBI_ECI, | ||
149 | .nranges = 3, | ||
150 | .range = (struct ab5500_reg_range[]) { | ||
151 | { | ||
152 | .first = 0x00, | ||
153 | .last = 0x07, | ||
154 | .perm = AB5500_PERM_RW, | ||
155 | }, | ||
156 | { | ||
157 | .first = 0x10, | ||
158 | .last = 0x10, | ||
159 | .perm = AB5500_PERM_RW, | ||
160 | }, | ||
161 | { | ||
162 | .first = 0x13, | ||
163 | .last = 0x13, | ||
164 | .perm = AB5500_PERM_RW, | ||
165 | }, | ||
166 | }, | ||
167 | }, | ||
168 | [AB5500_BANK_CHG] = { | ||
169 | .bankid = AB5500_BANK_CHG, | ||
170 | .nranges = 2, | ||
171 | .range = (struct ab5500_reg_range[]) { | ||
172 | { | ||
173 | .first = 0x11, | ||
174 | .last = 0x11, | ||
175 | .perm = AB5500_PERM_RO, | ||
176 | }, | ||
177 | { | ||
178 | .first = 0x12, | ||
179 | .last = 0x1B, | ||
180 | .perm = AB5500_PERM_RW, | ||
181 | }, | ||
182 | }, | ||
183 | }, | ||
184 | [AB5500_BANK_FG_BATTCOM_ACC] = { | ||
185 | .bankid = AB5500_BANK_FG_BATTCOM_ACC, | ||
186 | .nranges = 2, | ||
187 | .range = (struct ab5500_reg_range[]) { | ||
188 | { | ||
189 | .first = 0x00, | ||
190 | .last = 0x0B, | ||
191 | .perm = AB5500_PERM_RO, | ||
192 | }, | ||
193 | { | ||
194 | .first = 0x0C, | ||
195 | .last = 0x10, | ||
196 | .perm = AB5500_PERM_RW, | ||
197 | }, | ||
198 | }, | ||
199 | }, | ||
200 | [AB5500_BANK_USB] = { | ||
201 | .bankid = AB5500_BANK_USB, | ||
202 | .nranges = 12, | ||
203 | .range = (struct ab5500_reg_range[]) { | ||
204 | { | ||
205 | .first = 0x01, | ||
206 | .last = 0x01, | ||
207 | .perm = AB5500_PERM_RW, | ||
208 | }, | ||
209 | { | ||
210 | .first = 0x80, | ||
211 | .last = 0x83, | ||
212 | .perm = AB5500_PERM_RW, | ||
213 | }, | ||
214 | { | ||
215 | .first = 0x87, | ||
216 | .last = 0x8A, | ||
217 | .perm = AB5500_PERM_RW, | ||
218 | }, | ||
219 | { | ||
220 | .first = 0x8B, | ||
221 | .last = 0x8B, | ||
222 | .perm = AB5500_PERM_RO, | ||
223 | }, | ||
224 | { | ||
225 | .first = 0x91, | ||
226 | .last = 0x92, | ||
227 | .perm = AB5500_PERM_RO, | ||
228 | }, | ||
229 | { | ||
230 | .first = 0x93, | ||
231 | .last = 0x93, | ||
232 | .perm = AB5500_PERM_RW, | ||
233 | }, | ||
234 | { | ||
235 | .first = 0x94, | ||
236 | .last = 0x94, | ||
237 | .perm = AB5500_PERM_RO, | ||
238 | }, | ||
239 | { | ||
240 | .first = 0xA8, | ||
241 | .last = 0xB0, | ||
242 | .perm = AB5500_PERM_RO, | ||
243 | }, | ||
244 | { | ||
245 | .first = 0xB2, | ||
246 | .last = 0xB2, | ||
247 | .perm = AB5500_PERM_RO, | ||
248 | }, | ||
249 | { | ||
250 | .first = 0xB4, | ||
251 | .last = 0xBC, | ||
252 | .perm = AB5500_PERM_RO, | ||
253 | }, | ||
254 | { | ||
255 | .first = 0xBF, | ||
256 | .last = 0xBF, | ||
257 | .perm = AB5500_PERM_RO, | ||
258 | }, | ||
259 | { | ||
260 | .first = 0xC1, | ||
261 | .last = 0xC5, | ||
262 | .perm = AB5500_PERM_RO, | ||
263 | }, | ||
264 | }, | ||
265 | }, | ||
266 | [AB5500_BANK_IT] = { | ||
267 | .bankid = AB5500_BANK_IT, | ||
268 | .nranges = 4, | ||
269 | .range = (struct ab5500_reg_range[]) { | ||
270 | { | ||
271 | .first = 0x00, | ||
272 | .last = 0x02, | ||
273 | .perm = AB5500_PERM_RO, | ||
274 | }, | ||
275 | { | ||
276 | .first = 0x20, | ||
277 | .last = 0x36, | ||
278 | .perm = AB5500_PERM_RO, | ||
279 | }, | ||
280 | { | ||
281 | .first = 0x40, | ||
282 | .last = 0x56, | ||
283 | .perm = AB5500_PERM_RO, | ||
284 | }, | ||
285 | { | ||
286 | .first = 0x60, | ||
287 | .last = 0x76, | ||
288 | .perm = AB5500_PERM_RO, | ||
289 | }, | ||
290 | }, | ||
291 | }, | ||
292 | [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { | ||
293 | .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST, | ||
294 | .nranges = 7, | ||
295 | .range = (struct ab5500_reg_range[]) { | ||
296 | { | ||
297 | .first = 0x02, | ||
298 | .last = 0x02, | ||
299 | .perm = AB5500_PERM_RW, | ||
300 | }, | ||
301 | { | ||
302 | .first = 0x12, | ||
303 | .last = 0x12, | ||
304 | .perm = AB5500_PERM_RW, | ||
305 | }, | ||
306 | { | ||
307 | .first = 0x30, | ||
308 | .last = 0x34, | ||
309 | .perm = AB5500_PERM_RW, | ||
310 | }, | ||
311 | { | ||
312 | .first = 0x40, | ||
313 | .last = 0x44, | ||
314 | .perm = AB5500_PERM_RW, | ||
315 | }, | ||
316 | { | ||
317 | .first = 0x50, | ||
318 | .last = 0x54, | ||
319 | .perm = AB5500_PERM_RW, | ||
320 | }, | ||
321 | { | ||
322 | .first = 0x60, | ||
323 | .last = 0x64, | ||
324 | .perm = AB5500_PERM_RW, | ||
325 | }, | ||
326 | { | ||
327 | .first = 0x70, | ||
328 | .last = 0x74, | ||
329 | .perm = AB5500_PERM_RW, | ||
330 | }, | ||
331 | }, | ||
332 | }, | ||
333 | [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { | ||
334 | .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP, | ||
335 | .nranges = 13, | ||
336 | .range = (struct ab5500_reg_range[]) { | ||
337 | { | ||
338 | .first = 0x01, | ||
339 | .last = 0x01, | ||
340 | .perm = AB5500_PERM_RW, | ||
341 | }, | ||
342 | { | ||
343 | .first = 0x02, | ||
344 | .last = 0x02, | ||
345 | .perm = AB5500_PERM_RO, | ||
346 | }, | ||
347 | { | ||
348 | .first = 0x0D, | ||
349 | .last = 0x0F, | ||
350 | .perm = AB5500_PERM_RW, | ||
351 | }, | ||
352 | { | ||
353 | .first = 0x1C, | ||
354 | .last = 0x1C, | ||
355 | .perm = AB5500_PERM_RW, | ||
356 | }, | ||
357 | { | ||
358 | .first = 0x1E, | ||
359 | .last = 0x1E, | ||
360 | .perm = AB5500_PERM_RW, | ||
361 | }, | ||
362 | { | ||
363 | .first = 0x20, | ||
364 | .last = 0x21, | ||
365 | .perm = AB5500_PERM_RW, | ||
366 | }, | ||
367 | { | ||
368 | .first = 0x25, | ||
369 | .last = 0x25, | ||
370 | .perm = AB5500_PERM_RW, | ||
371 | }, | ||
372 | { | ||
373 | .first = 0x28, | ||
374 | .last = 0x2A, | ||
375 | .perm = AB5500_PERM_RW, | ||
376 | }, | ||
377 | { | ||
378 | .first = 0x30, | ||
379 | .last = 0x33, | ||
380 | .perm = AB5500_PERM_RW, | ||
381 | }, | ||
382 | { | ||
383 | .first = 0x40, | ||
384 | .last = 0x43, | ||
385 | .perm = AB5500_PERM_RW, | ||
386 | }, | ||
387 | { | ||
388 | .first = 0x50, | ||
389 | .last = 0x53, | ||
390 | .perm = AB5500_PERM_RW, | ||
391 | }, | ||
392 | { | ||
393 | .first = 0x60, | ||
394 | .last = 0x63, | ||
395 | .perm = AB5500_PERM_RW, | ||
396 | }, | ||
397 | { | ||
398 | .first = 0x70, | ||
399 | .last = 0x73, | ||
400 | .perm = AB5500_PERM_RW, | ||
401 | }, | ||
402 | }, | ||
403 | }, | ||
404 | [AB5500_BANK_VIBRA] = { | ||
405 | .bankid = AB5500_BANK_VIBRA, | ||
406 | .nranges = 2, | ||
407 | .range = (struct ab5500_reg_range[]) { | ||
408 | { | ||
409 | .first = 0x10, | ||
410 | .last = 0x13, | ||
411 | .perm = AB5500_PERM_RW, | ||
412 | }, | ||
413 | { | ||
414 | .first = 0xFE, | ||
415 | .last = 0xFE, | ||
416 | .perm = AB5500_PERM_RW, | ||
417 | }, | ||
418 | }, | ||
419 | }, | ||
420 | [AB5500_BANK_AUDIO_HEADSETUSB] = { | ||
421 | .bankid = AB5500_BANK_AUDIO_HEADSETUSB, | ||
422 | .nranges = 2, | ||
423 | .range = (struct ab5500_reg_range[]) { | ||
424 | { | ||
425 | .first = 0x00, | ||
426 | .last = 0x48, | ||
427 | .perm = AB5500_PERM_RW, | ||
428 | }, | ||
429 | { | ||
430 | .first = 0xEB, | ||
431 | .last = 0xFB, | ||
432 | .perm = AB5500_PERM_RW, | ||
433 | }, | ||
434 | }, | ||
435 | }, | ||
436 | [AB5500_BANK_SIM_USBSIM] = { | ||
437 | .bankid = AB5500_BANK_SIM_USBSIM, | ||
438 | .nranges = 1, | ||
439 | .range = (struct ab5500_reg_range[]) { | ||
440 | { | ||
441 | .first = 0x13, | ||
442 | .last = 0x19, | ||
443 | .perm = AB5500_PERM_RW, | ||
444 | }, | ||
445 | }, | ||
446 | }, | ||
447 | [AB5500_BANK_VDENC] = { | ||
448 | .bankid = AB5500_BANK_VDENC, | ||
449 | .nranges = 12, | ||
450 | .range = (struct ab5500_reg_range[]) { | ||
451 | { | ||
452 | .first = 0x00, | ||
453 | .last = 0x08, | ||
454 | .perm = AB5500_PERM_RW, | ||
455 | }, | ||
456 | { | ||
457 | .first = 0x09, | ||
458 | .last = 0x09, | ||
459 | .perm = AB5500_PERM_RO, | ||
460 | }, | ||
461 | { | ||
462 | .first = 0x0A, | ||
463 | .last = 0x12, | ||
464 | .perm = AB5500_PERM_RW, | ||
465 | }, | ||
466 | { | ||
467 | .first = 0x15, | ||
468 | .last = 0x19, | ||
469 | .perm = AB5500_PERM_RW, | ||
470 | }, | ||
471 | { | ||
472 | .first = 0x1B, | ||
473 | .last = 0x21, | ||
474 | .perm = AB5500_PERM_RW, | ||
475 | }, | ||
476 | { | ||
477 | .first = 0x27, | ||
478 | .last = 0x2C, | ||
479 | .perm = AB5500_PERM_RW, | ||
480 | }, | ||
481 | { | ||
482 | .first = 0x41, | ||
483 | .last = 0x41, | ||
484 | .perm = AB5500_PERM_RW, | ||
485 | }, | ||
486 | { | ||
487 | .first = 0x45, | ||
488 | .last = 0x5B, | ||
489 | .perm = AB5500_PERM_RW, | ||
490 | }, | ||
491 | { | ||
492 | .first = 0x5D, | ||
493 | .last = 0x5D, | ||
494 | .perm = AB5500_PERM_RW, | ||
495 | }, | ||
496 | { | ||
497 | .first = 0x69, | ||
498 | .last = 0x69, | ||
499 | .perm = AB5500_PERM_RW, | ||
500 | }, | ||
501 | { | ||
502 | .first = 0x6C, | ||
503 | .last = 0x6D, | ||
504 | .perm = AB5500_PERM_RW, | ||
505 | }, | ||
506 | { | ||
507 | .first = 0x80, | ||
508 | .last = 0x81, | ||
509 | .perm = AB5500_PERM_RW, | ||
510 | }, | ||
511 | }, | ||
512 | }, | ||
513 | }; | ||
514 | |||
515 | static int ab5500_registers_print(struct seq_file *s, void *p) | ||
516 | { | ||
517 | struct ab5500 *ab = s->private; | ||
518 | unsigned int i; | ||
519 | u8 bank = (u8)ab->debug_bank; | ||
520 | |||
521 | seq_printf(s, "ab5500 register values:\n"); | ||
522 | for (bank = 0; bank < AB5500_NUM_BANKS; bank++) { | ||
523 | seq_printf(s, " bank %u, %s (0x%x):\n", bank, | ||
524 | bankinfo[bank].name, | ||
525 | bankinfo[bank].slave_addr); | ||
526 | for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) { | ||
527 | u8 reg; | ||
528 | int err; | ||
529 | |||
530 | for (reg = ab5500_reg_ranges[bank].range[i].first; | ||
531 | reg <= ab5500_reg_ranges[bank].range[i].last; | ||
532 | reg++) { | ||
533 | u8 value; | ||
534 | |||
535 | err = ab5500_get_register_interruptible_raw(ab, | ||
536 | bank, reg, | ||
537 | &value); | ||
538 | if (err < 0) { | ||
539 | dev_err(ab->dev, "get_reg failed %d" | ||
540 | "bank 0x%x reg 0x%x\n", | ||
541 | err, bank, reg); | ||
542 | return err; | ||
543 | } | ||
544 | |||
545 | err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n", | ||
546 | bank, reg, value); | ||
547 | if (err < 0) { | ||
548 | dev_err(ab->dev, | ||
549 | "seq_printf overflow\n"); | ||
550 | /* | ||
551 | * Error is not returned here since | ||
552 | * the output is wanted in any case | ||
553 | */ | ||
554 | return 0; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static int ab5500_registers_open(struct inode *inode, struct file *file) | ||
563 | { | ||
564 | return single_open(file, ab5500_registers_print, inode->i_private); | ||
565 | } | ||
566 | |||
567 | static const struct file_operations ab5500_registers_fops = { | ||
568 | .open = ab5500_registers_open, | ||
569 | .read = seq_read, | ||
570 | .llseek = seq_lseek, | ||
571 | .release = single_release, | ||
572 | .owner = THIS_MODULE, | ||
573 | }; | ||
574 | |||
575 | static int ab5500_bank_print(struct seq_file *s, void *p) | ||
576 | { | ||
577 | struct ab5500 *ab = s->private; | ||
578 | |||
579 | seq_printf(s, "%d\n", ab->debug_bank); | ||
580 | return 0; | ||
581 | } | ||
582 | |||
583 | static int ab5500_bank_open(struct inode *inode, struct file *file) | ||
584 | { | ||
585 | return single_open(file, ab5500_bank_print, inode->i_private); | ||
586 | } | ||
587 | |||
588 | static ssize_t ab5500_bank_write(struct file *file, | ||
589 | const char __user *user_buf, | ||
590 | size_t count, loff_t *ppos) | ||
591 | { | ||
592 | struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; | ||
593 | char buf[32]; | ||
594 | int buf_size; | ||
595 | unsigned long user_bank; | ||
596 | int err; | ||
597 | |||
598 | /* Get userspace string and assure termination */ | ||
599 | buf_size = min(count, (sizeof(buf) - 1)); | ||
600 | if (copy_from_user(buf, user_buf, buf_size)) | ||
601 | return -EFAULT; | ||
602 | buf[buf_size] = 0; | ||
603 | |||
604 | err = strict_strtoul(buf, 0, &user_bank); | ||
605 | if (err) | ||
606 | return -EINVAL; | ||
607 | |||
608 | if (user_bank >= AB5500_NUM_BANKS) { | ||
609 | dev_err(ab->dev, | ||
610 | "debugfs error input > number of banks\n"); | ||
611 | return -EINVAL; | ||
612 | } | ||
613 | |||
614 | ab->debug_bank = user_bank; | ||
615 | |||
616 | return buf_size; | ||
617 | } | ||
618 | |||
619 | static int ab5500_address_print(struct seq_file *s, void *p) | ||
620 | { | ||
621 | struct ab5500 *ab = s->private; | ||
622 | |||
623 | seq_printf(s, "0x%02X\n", ab->debug_address); | ||
624 | return 0; | ||
625 | } | ||
626 | |||
627 | static int ab5500_address_open(struct inode *inode, struct file *file) | ||
628 | { | ||
629 | return single_open(file, ab5500_address_print, inode->i_private); | ||
630 | } | ||
631 | |||
632 | static ssize_t ab5500_address_write(struct file *file, | ||
633 | const char __user *user_buf, | ||
634 | size_t count, loff_t *ppos) | ||
635 | { | ||
636 | struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; | ||
637 | char buf[32]; | ||
638 | int buf_size; | ||
639 | unsigned long user_address; | ||
640 | int err; | ||
641 | |||
642 | /* Get userspace string and assure termination */ | ||
643 | buf_size = min(count, (sizeof(buf) - 1)); | ||
644 | if (copy_from_user(buf, user_buf, buf_size)) | ||
645 | return -EFAULT; | ||
646 | buf[buf_size] = 0; | ||
647 | |||
648 | err = strict_strtoul(buf, 0, &user_address); | ||
649 | if (err) | ||
650 | return -EINVAL; | ||
651 | if (user_address > 0xff) { | ||
652 | dev_err(ab->dev, | ||
653 | "debugfs error input > 0xff\n"); | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | ab->debug_address = user_address; | ||
657 | return buf_size; | ||
658 | } | ||
659 | |||
660 | static int ab5500_val_print(struct seq_file *s, void *p) | ||
661 | { | ||
662 | struct ab5500 *ab = s->private; | ||
663 | int err; | ||
664 | u8 regvalue; | ||
665 | |||
666 | err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, | ||
667 | (u8)ab->debug_address, ®value); | ||
668 | if (err) { | ||
669 | dev_err(ab->dev, "get_reg failed %d, bank 0x%x" | ||
670 | ", reg 0x%x\n", err, ab->debug_bank, | ||
671 | ab->debug_address); | ||
672 | return -EINVAL; | ||
673 | } | ||
674 | seq_printf(s, "0x%02X\n", regvalue); | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | static int ab5500_val_open(struct inode *inode, struct file *file) | ||
680 | { | ||
681 | return single_open(file, ab5500_val_print, inode->i_private); | ||
682 | } | ||
683 | |||
684 | static ssize_t ab5500_val_write(struct file *file, | ||
685 | const char __user *user_buf, | ||
686 | size_t count, loff_t *ppos) | ||
687 | { | ||
688 | struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private; | ||
689 | char buf[32]; | ||
690 | int buf_size; | ||
691 | unsigned long user_val; | ||
692 | int err; | ||
693 | u8 regvalue; | ||
694 | |||
695 | /* Get userspace string and assure termination */ | ||
696 | buf_size = min(count, (sizeof(buf)-1)); | ||
697 | if (copy_from_user(buf, user_buf, buf_size)) | ||
698 | return -EFAULT; | ||
699 | buf[buf_size] = 0; | ||
700 | |||
701 | err = strict_strtoul(buf, 0, &user_val); | ||
702 | if (err) | ||
703 | return -EINVAL; | ||
704 | if (user_val > 0xff) { | ||
705 | dev_err(ab->dev, | ||
706 | "debugfs error input > 0xff\n"); | ||
707 | return -EINVAL; | ||
708 | } | ||
709 | err = ab5500_mask_and_set_register_interruptible_raw( | ||
710 | ab, (u8)ab->debug_bank, | ||
711 | (u8)ab->debug_address, 0xFF, (u8)user_val); | ||
712 | if (err) | ||
713 | return -EINVAL; | ||
714 | |||
715 | ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank, | ||
716 | (u8)ab->debug_address, ®value); | ||
717 | if (err) | ||
718 | return -EINVAL; | ||
719 | |||
720 | return buf_size; | ||
721 | } | ||
722 | |||
723 | static const struct file_operations ab5500_bank_fops = { | ||
724 | .open = ab5500_bank_open, | ||
725 | .write = ab5500_bank_write, | ||
726 | .read = seq_read, | ||
727 | .llseek = seq_lseek, | ||
728 | .release = single_release, | ||
729 | .owner = THIS_MODULE, | ||
730 | }; | ||
731 | |||
732 | static const struct file_operations ab5500_address_fops = { | ||
733 | .open = ab5500_address_open, | ||
734 | .write = ab5500_address_write, | ||
735 | .read = seq_read, | ||
736 | .llseek = seq_lseek, | ||
737 | .release = single_release, | ||
738 | .owner = THIS_MODULE, | ||
739 | }; | ||
740 | |||
741 | static const struct file_operations ab5500_val_fops = { | ||
742 | .open = ab5500_val_open, | ||
743 | .write = ab5500_val_write, | ||
744 | .read = seq_read, | ||
745 | .llseek = seq_lseek, | ||
746 | .release = single_release, | ||
747 | .owner = THIS_MODULE, | ||
748 | }; | ||
749 | |||
750 | static struct dentry *ab5500_dir; | ||
751 | static struct dentry *ab5500_reg_file; | ||
752 | static struct dentry *ab5500_bank_file; | ||
753 | static struct dentry *ab5500_address_file; | ||
754 | static struct dentry *ab5500_val_file; | ||
755 | |||
756 | void __init ab5500_setup_debugfs(struct ab5500 *ab) | ||
757 | { | ||
758 | ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP; | ||
759 | ab->debug_address = AB5500_CHIP_ID; | ||
760 | |||
761 | ab5500_dir = debugfs_create_dir("ab5500", NULL); | ||
762 | if (!ab5500_dir) | ||
763 | goto exit_no_debugfs; | ||
764 | |||
765 | ab5500_reg_file = debugfs_create_file("all-bank-registers", | ||
766 | S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops); | ||
767 | if (!ab5500_reg_file) | ||
768 | goto exit_destroy_dir; | ||
769 | |||
770 | ab5500_bank_file = debugfs_create_file("register-bank", | ||
771 | (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops); | ||
772 | if (!ab5500_bank_file) | ||
773 | goto exit_destroy_reg; | ||
774 | |||
775 | ab5500_address_file = debugfs_create_file("register-address", | ||
776 | (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops); | ||
777 | if (!ab5500_address_file) | ||
778 | goto exit_destroy_bank; | ||
779 | |||
780 | ab5500_val_file = debugfs_create_file("register-value", | ||
781 | (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops); | ||
782 | if (!ab5500_val_file) | ||
783 | goto exit_destroy_address; | ||
784 | |||
785 | return; | ||
786 | |||
787 | exit_destroy_address: | ||
788 | debugfs_remove(ab5500_address_file); | ||
789 | exit_destroy_bank: | ||
790 | debugfs_remove(ab5500_bank_file); | ||
791 | exit_destroy_reg: | ||
792 | debugfs_remove(ab5500_reg_file); | ||
793 | exit_destroy_dir: | ||
794 | debugfs_remove(ab5500_dir); | ||
795 | exit_no_debugfs: | ||
796 | dev_err(ab->dev, "failed to create debugfs entries.\n"); | ||
797 | return; | ||
798 | } | ||
799 | |||
800 | void __exit ab5500_remove_debugfs(void) | ||
801 | { | ||
802 | debugfs_remove(ab5500_val_file); | ||
803 | debugfs_remove(ab5500_address_file); | ||
804 | debugfs_remove(ab5500_bank_file); | ||
805 | debugfs_remove(ab5500_reg_file); | ||
806 | debugfs_remove(ab5500_dir); | ||
807 | } | ||
diff --git a/drivers/mfd/ab5500-debugfs.h b/drivers/mfd/ab5500-debugfs.h deleted file mode 100644 index 7330a9b6afa6..000000000000 --- a/drivers/mfd/ab5500-debugfs.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 ST-Ericsson | ||
3 | * License terms: GNU General Public License (GPL) version 2 | ||
4 | * Debugfs interface to the AB5500 core driver | ||
5 | */ | ||
6 | |||
7 | #ifdef CONFIG_DEBUG_FS | ||
8 | |||
9 | void ab5500_setup_debugfs(struct ab5500 *ab); | ||
10 | void ab5500_remove_debugfs(void); | ||
11 | |||
12 | #else /* !CONFIG_DEBUG_FS */ | ||
13 | |||
14 | static inline void ab5500_setup_debugfs(struct ab5500 *ab) | ||
15 | { | ||
16 | } | ||
17 | |||
18 | static inline void ab5500_remove_debugfs(void) | ||
19 | { | ||
20 | } | ||
21 | |||
22 | #endif | ||
diff --git a/drivers/mfd/db5500-prcmu.c b/drivers/mfd/db5500-prcmu.c deleted file mode 100644 index bb115b2f04e9..000000000000 --- a/drivers/mfd/db5500-prcmu.c +++ /dev/null | |||
@@ -1,451 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
6 | * | ||
7 | * U5500 PRCM Unit interface driver | ||
8 | */ | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/mutex.h> | ||
18 | #include <linux/completion.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/mfd/dbx500-prcmu.h> | ||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/irqs.h> | ||
26 | #include <mach/db5500-regs.h> | ||
27 | #include "dbx500-prcmu-regs.h" | ||
28 | |||
29 | #define _PRCM_MB_HEADER (tcdm_base + 0xFE8) | ||
30 | #define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) | ||
31 | #define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1) | ||
32 | #define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2) | ||
33 | #define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3) | ||
34 | #define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4) | ||
35 | #define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5) | ||
36 | #define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6) | ||
37 | #define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7) | ||
38 | #define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8) | ||
39 | #define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9) | ||
40 | #define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa) | ||
41 | #define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb) | ||
42 | #define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc) | ||
43 | #define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd) | ||
44 | #define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe) | ||
45 | #define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf) | ||
46 | |||
47 | /* Req Mailboxes */ | ||
48 | #define PRCM_REQ_MB0 (tcdm_base + 0xFD8) | ||
49 | #define PRCM_REQ_MB1 (tcdm_base + 0xFCC) | ||
50 | #define PRCM_REQ_MB2 (tcdm_base + 0xFC4) | ||
51 | #define PRCM_REQ_MB3 (tcdm_base + 0xFC0) | ||
52 | #define PRCM_REQ_MB4 (tcdm_base + 0xF98) | ||
53 | #define PRCM_REQ_MB5 (tcdm_base + 0xF90) | ||
54 | #define PRCM_REQ_MB6 (tcdm_base + 0xF8C) | ||
55 | #define PRCM_REQ_MB7 (tcdm_base + 0xF84) | ||
56 | |||
57 | /* Ack Mailboxes */ | ||
58 | #define PRCM_ACK_MB0 (tcdm_base + 0xF38) | ||
59 | #define PRCM_ACK_MB1 (tcdm_base + 0xF30) | ||
60 | #define PRCM_ACK_MB2 (tcdm_base + 0xF24) | ||
61 | #define PRCM_ACK_MB3 (tcdm_base + 0xF20) | ||
62 | #define PRCM_ACK_MB4 (tcdm_base + 0xF1C) | ||
63 | #define PRCM_ACK_MB5 (tcdm_base + 0xF14) | ||
64 | #define PRCM_ACK_MB6 (tcdm_base + 0xF0C) | ||
65 | #define PRCM_ACK_MB7 (tcdm_base + 0xF08) | ||
66 | |||
67 | enum mb_return_code { | ||
68 | RC_SUCCESS, | ||
69 | RC_FAIL, | ||
70 | }; | ||
71 | |||
72 | /* Mailbox 0 headers. */ | ||
73 | enum mb0_header { | ||
74 | /* request */ | ||
75 | RMB0H_PWR_STATE_TRANS = 1, | ||
76 | RMB0H_WAKE_UP_CFG, | ||
77 | RMB0H_RD_WAKE_UP_ACK, | ||
78 | /* acknowledge */ | ||
79 | AMB0H_WAKE_UP = 1, | ||
80 | }; | ||
81 | |||
82 | /* Mailbox 5 headers. */ | ||
83 | enum mb5_header { | ||
84 | MB5H_I2C_WRITE = 1, | ||
85 | MB5H_I2C_READ, | ||
86 | }; | ||
87 | |||
88 | /* Request mailbox 5 fields. */ | ||
89 | #define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0) | ||
90 | #define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1) | ||
91 | #define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2) | ||
92 | #define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4) | ||
93 | |||
94 | /* Acknowledge mailbox 5 fields. */ | ||
95 | #define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0) | ||
96 | #define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4) | ||
97 | |||
98 | #define NUM_MB 8 | ||
99 | #define MBOX_BIT BIT | ||
100 | #define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) | ||
101 | |||
102 | /* | ||
103 | * Used by MCDE to setup all necessary PRCMU registers | ||
104 | */ | ||
105 | #define PRCMU_RESET_DSIPLL 0x00004000 | ||
106 | #define PRCMU_UNCLAMP_DSIPLL 0x00400800 | ||
107 | |||
108 | /* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/ | ||
109 | #define PRCMU_DSI_CLOCK_SETTING 0x00000128 | ||
110 | /* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ | ||
111 | #define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 | ||
112 | #define PRCMU_PLLDSI_FREQ_SETTING 0x00020121 | ||
113 | #define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 | ||
114 | #define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000201 | ||
115 | #define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 | ||
116 | |||
117 | #define PRCMU_ENABLE_PLLDSI 0x00000001 | ||
118 | #define PRCMU_DISABLE_PLLDSI 0x00000000 | ||
119 | |||
120 | #define PRCMU_DSI_RESET_SW 0x00000003 | ||
121 | #define PRCMU_RESOUTN0_PIN 0x00000001 | ||
122 | #define PRCMU_RESOUTN1_PIN 0x00000002 | ||
123 | #define PRCMU_RESOUTN2_PIN 0x00000004 | ||
124 | |||
125 | #define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 | ||
126 | |||
127 | /* | ||
128 | * mb0_transfer - state needed for mailbox 0 communication. | ||
129 | * @lock: The transaction lock. | ||
130 | */ | ||
131 | static struct { | ||
132 | spinlock_t lock; | ||
133 | } mb0_transfer; | ||
134 | |||
135 | /* | ||
136 | * mb5_transfer - state needed for mailbox 5 communication. | ||
137 | * @lock: The transaction lock. | ||
138 | * @work: The transaction completion structure. | ||
139 | * @ack: Reply ("acknowledge") data. | ||
140 | */ | ||
141 | static struct { | ||
142 | struct mutex lock; | ||
143 | struct completion work; | ||
144 | struct { | ||
145 | u8 header; | ||
146 | u8 status; | ||
147 | u8 value[4]; | ||
148 | } ack; | ||
149 | } mb5_transfer; | ||
150 | |||
151 | /* PRCMU TCDM base IO address. */ | ||
152 | static __iomem void *tcdm_base; | ||
153 | |||
154 | /** | ||
155 | * db5500_prcmu_abb_read() - Read register value(s) from the ABB. | ||
156 | * @slave: The I2C slave address. | ||
157 | * @reg: The (start) register address. | ||
158 | * @value: The read out value(s). | ||
159 | * @size: The number of registers to read. | ||
160 | * | ||
161 | * Reads register value(s) from the ABB. | ||
162 | * @size has to be <= 4. | ||
163 | */ | ||
164 | int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | ||
165 | { | ||
166 | int r; | ||
167 | |||
168 | if ((size < 1) || (4 < size)) | ||
169 | return -EINVAL; | ||
170 | |||
171 | mutex_lock(&mb5_transfer.lock); | ||
172 | |||
173 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | ||
174 | cpu_relax(); | ||
175 | writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); | ||
176 | writeb(reg, PRCM_REQ_MB5_I2C_REG); | ||
177 | writeb(size, PRCM_REQ_MB5_I2C_SIZE); | ||
178 | writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER); | ||
179 | |||
180 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); | ||
181 | wait_for_completion(&mb5_transfer.work); | ||
182 | |||
183 | r = 0; | ||
184 | if ((mb5_transfer.ack.header == MB5H_I2C_READ) && | ||
185 | (mb5_transfer.ack.status == RC_SUCCESS)) | ||
186 | memcpy(value, mb5_transfer.ack.value, (size_t)size); | ||
187 | else | ||
188 | r = -EIO; | ||
189 | |||
190 | mutex_unlock(&mb5_transfer.lock); | ||
191 | |||
192 | return r; | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * db5500_prcmu_abb_write() - Write register value(s) to the ABB. | ||
197 | * @slave: The I2C slave address. | ||
198 | * @reg: The (start) register address. | ||
199 | * @value: The value(s) to write. | ||
200 | * @size: The number of registers to write. | ||
201 | * | ||
202 | * Writes register value(s) to the ABB. | ||
203 | * @size has to be <= 4. | ||
204 | */ | ||
205 | int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | ||
206 | { | ||
207 | int r; | ||
208 | |||
209 | if ((size < 1) || (4 < size)) | ||
210 | return -EINVAL; | ||
211 | |||
212 | mutex_lock(&mb5_transfer.lock); | ||
213 | |||
214 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | ||
215 | cpu_relax(); | ||
216 | writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); | ||
217 | writeb(reg, PRCM_REQ_MB5_I2C_REG); | ||
218 | writeb(size, PRCM_REQ_MB5_I2C_SIZE); | ||
219 | memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size); | ||
220 | writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER); | ||
221 | |||
222 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); | ||
223 | wait_for_completion(&mb5_transfer.work); | ||
224 | |||
225 | if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) && | ||
226 | (mb5_transfer.ack.status == RC_SUCCESS)) | ||
227 | r = 0; | ||
228 | else | ||
229 | r = -EIO; | ||
230 | |||
231 | mutex_unlock(&mb5_transfer.lock); | ||
232 | |||
233 | return r; | ||
234 | } | ||
235 | |||
236 | int db5500_prcmu_enable_dsipll(void) | ||
237 | { | ||
238 | int i; | ||
239 | |||
240 | /* Enable DSIPLL_RESETN resets */ | ||
241 | writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); | ||
242 | /* Unclamp DSIPLL in/out */ | ||
243 | writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); | ||
244 | /* Set DSI PLL FREQ */ | ||
245 | writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ); | ||
246 | writel(PRCMU_DSI_PLLOUT_SEL_SETTING, | ||
247 | PRCM_DSI_PLLOUT_SEL); | ||
248 | /* Enable Escape clocks */ | ||
249 | writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); | ||
250 | |||
251 | /* Start DSI PLL */ | ||
252 | writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); | ||
253 | /* Reset DSI PLL */ | ||
254 | writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); | ||
255 | for (i = 0; i < 10; i++) { | ||
256 | if ((readl(PRCM_PLLDSI_LOCKP) & | ||
257 | PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED) | ||
258 | break; | ||
259 | udelay(100); | ||
260 | } | ||
261 | /* Release DSIPLL_RESETN */ | ||
262 | writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); | ||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | int db5500_prcmu_disable_dsipll(void) | ||
267 | { | ||
268 | /* Disable dsi pll */ | ||
269 | writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); | ||
270 | /* Disable escapeclock */ | ||
271 | writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | int db5500_prcmu_set_display_clocks(void) | ||
276 | { | ||
277 | /* HDMI and TVCLK Should be handled somewhere else */ | ||
278 | /* PLLDIV=8, PLLSW=2, CLKEN=1 */ | ||
279 | writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); | ||
280 | /* PLLDIV=14, PLLSW=2, CLKEN=1 */ | ||
281 | writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void ack_dbb_wakeup(void) | ||
286 | { | ||
287 | unsigned long flags; | ||
288 | |||
289 | spin_lock_irqsave(&mb0_transfer.lock, flags); | ||
290 | |||
291 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) | ||
292 | cpu_relax(); | ||
293 | |||
294 | writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER); | ||
295 | writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); | ||
296 | |||
297 | spin_unlock_irqrestore(&mb0_transfer.lock, flags); | ||
298 | } | ||
299 | |||
300 | static inline void print_unknown_header_warning(u8 n, u8 header) | ||
301 | { | ||
302 | pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", | ||
303 | header, n); | ||
304 | } | ||
305 | |||
306 | static bool read_mailbox_0(void) | ||
307 | { | ||
308 | bool r; | ||
309 | u8 header; | ||
310 | |||
311 | header = readb(PRCM_ACK_MB0_HEADER); | ||
312 | switch (header) { | ||
313 | case AMB0H_WAKE_UP: | ||
314 | r = true; | ||
315 | break; | ||
316 | default: | ||
317 | print_unknown_header_warning(0, header); | ||
318 | r = false; | ||
319 | break; | ||
320 | } | ||
321 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR); | ||
322 | return r; | ||
323 | } | ||
324 | |||
325 | static bool read_mailbox_1(void) | ||
326 | { | ||
327 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR); | ||
328 | return false; | ||
329 | } | ||
330 | |||
331 | static bool read_mailbox_2(void) | ||
332 | { | ||
333 | writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR); | ||
334 | return false; | ||
335 | } | ||
336 | |||
337 | static bool read_mailbox_3(void) | ||
338 | { | ||
339 | writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR); | ||
340 | return false; | ||
341 | } | ||
342 | |||
343 | static bool read_mailbox_4(void) | ||
344 | { | ||
345 | writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR); | ||
346 | return false; | ||
347 | } | ||
348 | |||
349 | static bool read_mailbox_5(void) | ||
350 | { | ||
351 | u8 header; | ||
352 | |||
353 | header = readb(PRCM_ACK_MB5_HEADER); | ||
354 | switch (header) { | ||
355 | case MB5H_I2C_READ: | ||
356 | memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4); | ||
357 | case MB5H_I2C_WRITE: | ||
358 | mb5_transfer.ack.header = header; | ||
359 | mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE); | ||
360 | complete(&mb5_transfer.work); | ||
361 | break; | ||
362 | default: | ||
363 | print_unknown_header_warning(5, header); | ||
364 | break; | ||
365 | } | ||
366 | writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR); | ||
367 | return false; | ||
368 | } | ||
369 | |||
370 | static bool read_mailbox_6(void) | ||
371 | { | ||
372 | writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR); | ||
373 | return false; | ||
374 | } | ||
375 | |||
376 | static bool read_mailbox_7(void) | ||
377 | { | ||
378 | writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR); | ||
379 | return false; | ||
380 | } | ||
381 | |||
382 | static bool (* const read_mailbox[NUM_MB])(void) = { | ||
383 | read_mailbox_0, | ||
384 | read_mailbox_1, | ||
385 | read_mailbox_2, | ||
386 | read_mailbox_3, | ||
387 | read_mailbox_4, | ||
388 | read_mailbox_5, | ||
389 | read_mailbox_6, | ||
390 | read_mailbox_7 | ||
391 | }; | ||
392 | |||
393 | static irqreturn_t prcmu_irq_handler(int irq, void *data) | ||
394 | { | ||
395 | u32 bits; | ||
396 | u8 n; | ||
397 | irqreturn_t r; | ||
398 | |||
399 | bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); | ||
400 | if (unlikely(!bits)) | ||
401 | return IRQ_NONE; | ||
402 | |||
403 | r = IRQ_HANDLED; | ||
404 | for (n = 0; bits; n++) { | ||
405 | if (bits & MBOX_BIT(n)) { | ||
406 | bits -= MBOX_BIT(n); | ||
407 | if (read_mailbox[n]()) | ||
408 | r = IRQ_WAKE_THREAD; | ||
409 | } | ||
410 | } | ||
411 | return r; | ||
412 | } | ||
413 | |||
414 | static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) | ||
415 | { | ||
416 | ack_dbb_wakeup(); | ||
417 | return IRQ_HANDLED; | ||
418 | } | ||
419 | |||
420 | void __init db5500_prcmu_early_init(void) | ||
421 | { | ||
422 | tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE); | ||
423 | spin_lock_init(&mb0_transfer.lock); | ||
424 | mutex_init(&mb5_transfer.lock); | ||
425 | init_completion(&mb5_transfer.work); | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic | ||
430 | * | ||
431 | */ | ||
432 | int __init db5500_prcmu_init(void) | ||
433 | { | ||
434 | int r = 0; | ||
435 | |||
436 | if (ux500_is_svp() || !cpu_is_u5500()) | ||
437 | return -ENODEV; | ||
438 | |||
439 | /* Clean up the mailbox interrupts after pre-kernel code. */ | ||
440 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); | ||
441 | |||
442 | r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, | ||
443 | prcmu_irq_thread_fn, 0, "prcmu", NULL); | ||
444 | if (r < 0) { | ||
445 | pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n"); | ||
446 | return -EBUSY; | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | arch_initcall(db5500_prcmu_init); | ||
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c index 2e42ec2e8ff4..04769a49a7cb 100644 --- a/drivers/mtd/nand/autcpu12.c +++ b/drivers/mtd/nand/autcpu12.c | |||
@@ -102,10 +102,10 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd, | |||
102 | void __iomem *addr; | 102 | void __iomem *addr; |
103 | unsigned char bits; | 103 | unsigned char bits; |
104 | 104 | ||
105 | addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET; | 105 | bits = clps_readb(AUTCPU12_SMC_PORT_OFFSET) & ~0x30; |
106 | bits = (ctrl & NAND_CLE) << 4; | 106 | bits |= (ctrl & NAND_CLE) << 4; |
107 | bits |= (ctrl & NAND_ALE) << 2; | 107 | bits |= (ctrl & NAND_ALE) << 2; |
108 | writeb((readb(addr) & ~0x30) | bits, addr); | 108 | clps_writeb(bits, AUTCPU12_SMC_PORT_OFFSET); |
109 | 109 | ||
110 | addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET; | 110 | addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET; |
111 | writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr); | 111 | writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr); |
@@ -120,9 +120,7 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd, | |||
120 | */ | 120 | */ |
121 | int autcpu12_device_ready(struct mtd_info *mtd) | 121 | int autcpu12_device_ready(struct mtd_info *mtd) |
122 | { | 122 | { |
123 | void __iomem *addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET; | 123 | return clps_readb(AUTCPU12_SMC_PORT_OFFSET) & AUTCPU12_SMC_RDY; |
124 | |||
125 | return readb(addr) & AUTCPU12_SMC_RDY; | ||
126 | } | 124 | } |
127 | 125 | ||
128 | /* | 126 | /* |
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c index 11e487813428..9bf5ce5fa22d 100644 --- a/drivers/mtd/nand/h1910.c +++ b/drivers/mtd/nand/h1910.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/mtd/nand.h> | 24 | #include <linux/mtd/nand.h> |
25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <mach/hardware.h> /* for CLPS7111_VIRT_BASE */ | 27 | #include <mach/hardware.h> |
28 | #include <asm/sizes.h> | 28 | #include <asm/sizes.h> |
29 | #include <mach/h1900-gpio.h> | 29 | #include <mach/h1900-gpio.h> |
30 | #include <mach/ipaq.h> | 30 | #include <mach/ipaq.h> |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 35758445297e..031d8e8ed1ad 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -211,8 +211,8 @@ config KINGSUN_DONGLE | |||
211 | kingsun-sir. | 211 | kingsun-sir. |
212 | 212 | ||
213 | config EP7211_DONGLE | 213 | config EP7211_DONGLE |
214 | tristate "EP7211 I/R support" | 214 | tristate "Cirrus Logic clps711x I/R support" |
215 | depends on IRTTY_SIR && ARCH_EP7211 && IRDA && EXPERIMENTAL | 215 | depends on IRTTY_SIR && ARCH_CLPS711X && IRDA && EXPERIMENTAL |
216 | help | 216 | help |
217 | Say Y here if you want to build support for the Cirrus logic | 217 | Say Y here if you want to build support for the Cirrus logic |
218 | EP7211 chipset's infrared module. | 218 | EP7211 chipset's infrared module. |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8c8377d50c4c..4161bfe462cd 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -838,7 +838,7 @@ config RTC_DRV_AT32AP700X | |||
838 | 838 | ||
839 | config RTC_DRV_AT91RM9200 | 839 | config RTC_DRV_AT91RM9200 |
840 | tristate "AT91RM9200 or some AT91SAM9 RTC" | 840 | tristate "AT91RM9200 or some AT91SAM9 RTC" |
841 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 | 841 | depends on ARCH_AT91 |
842 | help | 842 | help |
843 | Driver for the internal RTC (Realtime Clock) module found on | 843 | Driver for the internal RTC (Realtime Clock) module found on |
844 | Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips | 844 | Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips |
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 836fe2731234..d0f719fafc84 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -40,7 +40,6 @@ | |||
40 | 40 | ||
41 | #include <mach/hardware.h> | 41 | #include <mach/hardware.h> |
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | #include <asm/hardware/clps7111.h> | ||
44 | 43 | ||
45 | #define UART_NR 2 | 44 | #define UART_NR 2 |
46 | 45 | ||
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 96451e41ee8a..71229cb97e3e 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -205,8 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd) | |||
205 | need_transceiver = need_transceiver | 205 | need_transceiver = need_transceiver |
206 | || machine_is_omap_h2() || machine_is_omap_h3(); | 206 | || machine_is_omap_h2() || machine_is_omap_h3(); |
207 | 207 | ||
208 | if (cpu_is_omap16xx()) | 208 | /* XXX OMAP16xx only */ |
209 | ocpi_enable(); | 209 | if (config->ocpi_enable) |
210 | config->ocpi_enable(); | ||
210 | 211 | ||
211 | #ifdef CONFIG_USB_OTG | 212 | #ifdef CONFIG_USB_OTG |
212 | if (need_transceiver) { | 213 | if (need_transceiver) { |
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 99b354b8e257..f994c8b8f10a 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
34 | #include <linux/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | 35 | ||
36 | #include <asm/hardware/clps7111.h> | ||
37 | #include <mach/syspld.h> | 36 | #include <mach/syspld.h> |
38 | 37 | ||
39 | struct fb_info *cfb; | 38 | struct fb_info *cfb; |
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 408a9927be92..c3853c92279b 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig | |||
@@ -10,12 +10,12 @@ config PANEL_GENERIC_DPI | |||
10 | Supports LCD Panel used in TI SDP3430 and EVM boards, | 10 | Supports LCD Panel used in TI SDP3430 and EVM boards, |
11 | OMAP3517 EVM boards and CM-T35. | 11 | OMAP3517 EVM boards and CM-T35. |
12 | 12 | ||
13 | config PANEL_DVI | 13 | config PANEL_TFP410 |
14 | tristate "DVI output" | 14 | tristate "TFP410 DPI-to-DVI chip" |
15 | depends on OMAP2_DSS_DPI && I2C | 15 | depends on OMAP2_DSS_DPI && I2C |
16 | help | 16 | help |
17 | Driver for external monitors, connected via DVI. The driver uses i2c | 17 | Driver for TFP410 DPI-to-DVI chip. The driver uses i2c to read EDID |
18 | to read EDID information from the monitor. | 18 | information from the monitor. |
19 | 19 | ||
20 | config PANEL_LGPHILIPS_LB035Q02 | 20 | config PANEL_LGPHILIPS_LB035Q02 |
21 | tristate "LG.Philips LB035Q02 LCD Panel" | 21 | tristate "LG.Philips LB035Q02 LCD Panel" |
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index fbfafc6eebb4..58a5176b07b0 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o | 1 | obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o |
2 | obj-$(CONFIG_PANEL_DVI) += panel-dvi.o | 2 | obj-$(CONFIG_PANEL_TFP410) += panel-tfp410.o |
3 | obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o | 3 | obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o |
4 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o | 4 | obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o |
5 | obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o | 5 | obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o |
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 0f21fa5a16ae..b2dd88b48420 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c | |||
@@ -993,6 +993,15 @@ static int taal_probe(struct omap_dss_device *dssdev) | |||
993 | 993 | ||
994 | dev_set_drvdata(&dssdev->dev, td); | 994 | dev_set_drvdata(&dssdev->dev, td); |
995 | 995 | ||
996 | if (gpio_is_valid(panel_data->reset_gpio)) { | ||
997 | r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW, | ||
998 | "taal rst"); | ||
999 | if (r) { | ||
1000 | dev_err(&dssdev->dev, "failed to request reset gpio\n"); | ||
1001 | goto err_rst_gpio; | ||
1002 | } | ||
1003 | } | ||
1004 | |||
996 | taal_hw_reset(dssdev); | 1005 | taal_hw_reset(dssdev); |
997 | 1006 | ||
998 | if (panel_data->use_dsi_backlight) { | 1007 | if (panel_data->use_dsi_backlight) { |
@@ -1073,6 +1082,9 @@ err_gpio: | |||
1073 | if (bldev != NULL) | 1082 | if (bldev != NULL) |
1074 | backlight_device_unregister(bldev); | 1083 | backlight_device_unregister(bldev); |
1075 | err_bl: | 1084 | err_bl: |
1085 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
1086 | gpio_free(panel_data->reset_gpio); | ||
1087 | err_rst_gpio: | ||
1076 | destroy_workqueue(td->workqueue); | 1088 | destroy_workqueue(td->workqueue); |
1077 | err_wq: | 1089 | err_wq: |
1078 | free_regulators(panel_config->regulators, panel_config->num_regulators); | 1090 | free_regulators(panel_config->regulators, panel_config->num_regulators); |
@@ -1116,15 +1128,25 @@ static void __exit taal_remove(struct omap_dss_device *dssdev) | |||
1116 | free_regulators(td->panel_config->regulators, | 1128 | free_regulators(td->panel_config->regulators, |
1117 | td->panel_config->num_regulators); | 1129 | td->panel_config->num_regulators); |
1118 | 1130 | ||
1131 | if (gpio_is_valid(panel_data->reset_gpio)) | ||
1132 | gpio_free(panel_data->reset_gpio); | ||
1133 | |||
1119 | kfree(td); | 1134 | kfree(td); |
1120 | } | 1135 | } |
1121 | 1136 | ||
1122 | static int taal_power_on(struct omap_dss_device *dssdev) | 1137 | static int taal_power_on(struct omap_dss_device *dssdev) |
1123 | { | 1138 | { |
1124 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); | 1139 | struct taal_data *td = dev_get_drvdata(&dssdev->dev); |
1140 | struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev); | ||
1125 | u8 id1, id2, id3; | 1141 | u8 id1, id2, id3; |
1126 | int r; | 1142 | int r; |
1127 | 1143 | ||
1144 | r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config); | ||
1145 | if (r) { | ||
1146 | dev_err(&dssdev->dev, "failed to configure DSI pins\n"); | ||
1147 | goto err0; | ||
1148 | }; | ||
1149 | |||
1128 | r = omapdss_dsi_display_enable(dssdev); | 1150 | r = omapdss_dsi_display_enable(dssdev); |
1129 | if (r) { | 1151 | if (r) { |
1130 | dev_err(&dssdev->dev, "failed to enable DSI\n"); | 1152 | dev_err(&dssdev->dev, "failed to enable DSI\n"); |
diff --git a/drivers/video/omap2/displays/panel-dvi.c b/drivers/video/omap2/displays/panel-tfp410.c index 03eb14af33e0..52637fa8fda8 100644 --- a/drivers/video/omap2/displays/panel-dvi.c +++ b/drivers/video/omap2/displays/panel-tfp410.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * DVI output support | 2 | * TFP410 DPI-to-DVI chip |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Texas Instruments Inc | 4 | * Copyright (C) 2011 Texas Instruments Inc |
5 | * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> | 5 | * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> |
@@ -21,11 +21,12 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <video/omapdss.h> | 22 | #include <video/omapdss.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/gpio.h> | ||
24 | #include <drm/drm_edid.h> | 25 | #include <drm/drm_edid.h> |
25 | 26 | ||
26 | #include <video/omap-panel-dvi.h> | 27 | #include <video/omap-panel-tfp410.h> |
27 | 28 | ||
28 | static const struct omap_video_timings panel_dvi_default_timings = { | 29 | static const struct omap_video_timings tfp410_default_timings = { |
29 | .x_res = 640, | 30 | .x_res = 640, |
30 | .y_res = 480, | 31 | .y_res = 480, |
31 | 32 | ||
@@ -44,17 +45,19 @@ struct panel_drv_data { | |||
44 | struct omap_dss_device *dssdev; | 45 | struct omap_dss_device *dssdev; |
45 | 46 | ||
46 | struct mutex lock; | 47 | struct mutex lock; |
48 | |||
49 | int pd_gpio; | ||
47 | }; | 50 | }; |
48 | 51 | ||
49 | static inline struct panel_dvi_platform_data | 52 | static inline struct tfp410_platform_data |
50 | *get_pdata(const struct omap_dss_device *dssdev) | 53 | *get_pdata(const struct omap_dss_device *dssdev) |
51 | { | 54 | { |
52 | return dssdev->data; | 55 | return dssdev->data; |
53 | } | 56 | } |
54 | 57 | ||
55 | static int panel_dvi_power_on(struct omap_dss_device *dssdev) | 58 | static int tfp410_power_on(struct omap_dss_device *dssdev) |
56 | { | 59 | { |
57 | struct panel_dvi_platform_data *pdata = get_pdata(dssdev); | 60 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
58 | int r; | 61 | int r; |
59 | 62 | ||
60 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) | 63 | if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) |
@@ -64,57 +67,72 @@ static int panel_dvi_power_on(struct omap_dss_device *dssdev) | |||
64 | if (r) | 67 | if (r) |
65 | goto err0; | 68 | goto err0; |
66 | 69 | ||
67 | if (pdata->platform_enable) { | 70 | if (gpio_is_valid(ddata->pd_gpio)) |
68 | r = pdata->platform_enable(dssdev); | 71 | gpio_set_value(ddata->pd_gpio, 1); |
69 | if (r) | ||
70 | goto err1; | ||
71 | } | ||
72 | 72 | ||
73 | return 0; | 73 | return 0; |
74 | err1: | ||
75 | omapdss_dpi_display_disable(dssdev); | ||
76 | err0: | 74 | err0: |
77 | return r; | 75 | return r; |
78 | } | 76 | } |
79 | 77 | ||
80 | static void panel_dvi_power_off(struct omap_dss_device *dssdev) | 78 | static void tfp410_power_off(struct omap_dss_device *dssdev) |
81 | { | 79 | { |
82 | struct panel_dvi_platform_data *pdata = get_pdata(dssdev); | 80 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
83 | 81 | ||
84 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) | 82 | if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) |
85 | return; | 83 | return; |
86 | 84 | ||
87 | if (pdata->platform_disable) | 85 | if (gpio_is_valid(ddata->pd_gpio)) |
88 | pdata->platform_disable(dssdev); | 86 | gpio_set_value(ddata->pd_gpio, 0); |
89 | 87 | ||
90 | omapdss_dpi_display_disable(dssdev); | 88 | omapdss_dpi_display_disable(dssdev); |
91 | } | 89 | } |
92 | 90 | ||
93 | static int panel_dvi_probe(struct omap_dss_device *dssdev) | 91 | static int tfp410_probe(struct omap_dss_device *dssdev) |
94 | { | 92 | { |
93 | struct tfp410_platform_data *pdata = get_pdata(dssdev); | ||
95 | struct panel_drv_data *ddata; | 94 | struct panel_drv_data *ddata; |
95 | int r; | ||
96 | 96 | ||
97 | ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); | 97 | ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); |
98 | if (!ddata) | 98 | if (!ddata) |
99 | return -ENOMEM; | 99 | return -ENOMEM; |
100 | 100 | ||
101 | dssdev->panel.timings = panel_dvi_default_timings; | 101 | dssdev->panel.timings = tfp410_default_timings; |
102 | dssdev->panel.config = OMAP_DSS_LCD_TFT; | 102 | dssdev->panel.config = OMAP_DSS_LCD_TFT; |
103 | 103 | ||
104 | ddata->dssdev = dssdev; | 104 | ddata->dssdev = dssdev; |
105 | mutex_init(&ddata->lock); | 105 | mutex_init(&ddata->lock); |
106 | 106 | ||
107 | if (pdata) | ||
108 | ddata->pd_gpio = pdata->power_down_gpio; | ||
109 | else | ||
110 | ddata->pd_gpio = -1; | ||
111 | |||
112 | if (gpio_is_valid(ddata->pd_gpio)) { | ||
113 | r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW, | ||
114 | "tfp410 pd"); | ||
115 | if (r) { | ||
116 | dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n", | ||
117 | ddata->pd_gpio); | ||
118 | ddata->pd_gpio = -1; | ||
119 | } | ||
120 | } | ||
121 | |||
107 | dev_set_drvdata(&dssdev->dev, ddata); | 122 | dev_set_drvdata(&dssdev->dev, ddata); |
108 | 123 | ||
109 | return 0; | 124 | return 0; |
110 | } | 125 | } |
111 | 126 | ||
112 | static void __exit panel_dvi_remove(struct omap_dss_device *dssdev) | 127 | static void __exit tfp410_remove(struct omap_dss_device *dssdev) |
113 | { | 128 | { |
114 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 129 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
115 | 130 | ||
116 | mutex_lock(&ddata->lock); | 131 | mutex_lock(&ddata->lock); |
117 | 132 | ||
133 | if (gpio_is_valid(ddata->pd_gpio)) | ||
134 | gpio_free(ddata->pd_gpio); | ||
135 | |||
118 | dev_set_drvdata(&dssdev->dev, NULL); | 136 | dev_set_drvdata(&dssdev->dev, NULL); |
119 | 137 | ||
120 | mutex_unlock(&ddata->lock); | 138 | mutex_unlock(&ddata->lock); |
@@ -122,14 +140,14 @@ static void __exit panel_dvi_remove(struct omap_dss_device *dssdev) | |||
122 | kfree(ddata); | 140 | kfree(ddata); |
123 | } | 141 | } |
124 | 142 | ||
125 | static int panel_dvi_enable(struct omap_dss_device *dssdev) | 143 | static int tfp410_enable(struct omap_dss_device *dssdev) |
126 | { | 144 | { |
127 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 145 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
128 | int r; | 146 | int r; |
129 | 147 | ||
130 | mutex_lock(&ddata->lock); | 148 | mutex_lock(&ddata->lock); |
131 | 149 | ||
132 | r = panel_dvi_power_on(dssdev); | 150 | r = tfp410_power_on(dssdev); |
133 | if (r == 0) | 151 | if (r == 0) |
134 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | 152 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; |
135 | 153 | ||
@@ -138,26 +156,26 @@ static int panel_dvi_enable(struct omap_dss_device *dssdev) | |||
138 | return r; | 156 | return r; |
139 | } | 157 | } |
140 | 158 | ||
141 | static void panel_dvi_disable(struct omap_dss_device *dssdev) | 159 | static void tfp410_disable(struct omap_dss_device *dssdev) |
142 | { | 160 | { |
143 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 161 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
144 | 162 | ||
145 | mutex_lock(&ddata->lock); | 163 | mutex_lock(&ddata->lock); |
146 | 164 | ||
147 | panel_dvi_power_off(dssdev); | 165 | tfp410_power_off(dssdev); |
148 | 166 | ||
149 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; | 167 | dssdev->state = OMAP_DSS_DISPLAY_DISABLED; |
150 | 168 | ||
151 | mutex_unlock(&ddata->lock); | 169 | mutex_unlock(&ddata->lock); |
152 | } | 170 | } |
153 | 171 | ||
154 | static int panel_dvi_suspend(struct omap_dss_device *dssdev) | 172 | static int tfp410_suspend(struct omap_dss_device *dssdev) |
155 | { | 173 | { |
156 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 174 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
157 | 175 | ||
158 | mutex_lock(&ddata->lock); | 176 | mutex_lock(&ddata->lock); |
159 | 177 | ||
160 | panel_dvi_power_off(dssdev); | 178 | tfp410_power_off(dssdev); |
161 | 179 | ||
162 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; | 180 | dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; |
163 | 181 | ||
@@ -166,14 +184,14 @@ static int panel_dvi_suspend(struct omap_dss_device *dssdev) | |||
166 | return 0; | 184 | return 0; |
167 | } | 185 | } |
168 | 186 | ||
169 | static int panel_dvi_resume(struct omap_dss_device *dssdev) | 187 | static int tfp410_resume(struct omap_dss_device *dssdev) |
170 | { | 188 | { |
171 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 189 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
172 | int r; | 190 | int r; |
173 | 191 | ||
174 | mutex_lock(&ddata->lock); | 192 | mutex_lock(&ddata->lock); |
175 | 193 | ||
176 | r = panel_dvi_power_on(dssdev); | 194 | r = tfp410_power_on(dssdev); |
177 | if (r == 0) | 195 | if (r == 0) |
178 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; | 196 | dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; |
179 | 197 | ||
@@ -182,7 +200,7 @@ static int panel_dvi_resume(struct omap_dss_device *dssdev) | |||
182 | return r; | 200 | return r; |
183 | } | 201 | } |
184 | 202 | ||
185 | static void panel_dvi_set_timings(struct omap_dss_device *dssdev, | 203 | static void tfp410_set_timings(struct omap_dss_device *dssdev, |
186 | struct omap_video_timings *timings) | 204 | struct omap_video_timings *timings) |
187 | { | 205 | { |
188 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 206 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
@@ -192,7 +210,7 @@ static void panel_dvi_set_timings(struct omap_dss_device *dssdev, | |||
192 | mutex_unlock(&ddata->lock); | 210 | mutex_unlock(&ddata->lock); |
193 | } | 211 | } |
194 | 212 | ||
195 | static void panel_dvi_get_timings(struct omap_dss_device *dssdev, | 213 | static void tfp410_get_timings(struct omap_dss_device *dssdev, |
196 | struct omap_video_timings *timings) | 214 | struct omap_video_timings *timings) |
197 | { | 215 | { |
198 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 216 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
@@ -202,7 +220,7 @@ static void panel_dvi_get_timings(struct omap_dss_device *dssdev, | |||
202 | mutex_unlock(&ddata->lock); | 220 | mutex_unlock(&ddata->lock); |
203 | } | 221 | } |
204 | 222 | ||
205 | static int panel_dvi_check_timings(struct omap_dss_device *dssdev, | 223 | static int tfp410_check_timings(struct omap_dss_device *dssdev, |
206 | struct omap_video_timings *timings) | 224 | struct omap_video_timings *timings) |
207 | { | 225 | { |
208 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 226 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
@@ -216,7 +234,7 @@ static int panel_dvi_check_timings(struct omap_dss_device *dssdev, | |||
216 | } | 234 | } |
217 | 235 | ||
218 | 236 | ||
219 | static int panel_dvi_ddc_read(struct i2c_adapter *adapter, | 237 | static int tfp410_ddc_read(struct i2c_adapter *adapter, |
220 | unsigned char *buf, u16 count, u8 offset) | 238 | unsigned char *buf, u16 count, u8 offset) |
221 | { | 239 | { |
222 | int r, retries; | 240 | int r, retries; |
@@ -247,11 +265,11 @@ static int panel_dvi_ddc_read(struct i2c_adapter *adapter, | |||
247 | return r < 0 ? r : -EIO; | 265 | return r < 0 ? r : -EIO; |
248 | } | 266 | } |
249 | 267 | ||
250 | static int panel_dvi_read_edid(struct omap_dss_device *dssdev, | 268 | static int tfp410_read_edid(struct omap_dss_device *dssdev, |
251 | u8 *edid, int len) | 269 | u8 *edid, int len) |
252 | { | 270 | { |
253 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 271 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
254 | struct panel_dvi_platform_data *pdata = get_pdata(dssdev); | 272 | struct tfp410_platform_data *pdata = get_pdata(dssdev); |
255 | struct i2c_adapter *adapter; | 273 | struct i2c_adapter *adapter; |
256 | int r, l, bytes_read; | 274 | int r, l, bytes_read; |
257 | 275 | ||
@@ -271,7 +289,7 @@ static int panel_dvi_read_edid(struct omap_dss_device *dssdev, | |||
271 | } | 289 | } |
272 | 290 | ||
273 | l = min(EDID_LENGTH, len); | 291 | l = min(EDID_LENGTH, len); |
274 | r = panel_dvi_ddc_read(adapter, edid, l, 0); | 292 | r = tfp410_ddc_read(adapter, edid, l, 0); |
275 | if (r) | 293 | if (r) |
276 | goto err; | 294 | goto err; |
277 | 295 | ||
@@ -281,7 +299,7 @@ static int panel_dvi_read_edid(struct omap_dss_device *dssdev, | |||
281 | if (len > EDID_LENGTH && edid[0x7e] > 0) { | 299 | if (len > EDID_LENGTH && edid[0x7e] > 0) { |
282 | l = min(EDID_LENGTH, len - EDID_LENGTH); | 300 | l = min(EDID_LENGTH, len - EDID_LENGTH); |
283 | 301 | ||
284 | r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH, | 302 | r = tfp410_ddc_read(adapter, edid + EDID_LENGTH, |
285 | l, EDID_LENGTH); | 303 | l, EDID_LENGTH); |
286 | if (r) | 304 | if (r) |
287 | goto err; | 305 | goto err; |
@@ -298,10 +316,10 @@ err: | |||
298 | return r; | 316 | return r; |
299 | } | 317 | } |
300 | 318 | ||
301 | static bool panel_dvi_detect(struct omap_dss_device *dssdev) | 319 | static bool tfp410_detect(struct omap_dss_device *dssdev) |
302 | { | 320 | { |
303 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); | 321 | struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); |
304 | struct panel_dvi_platform_data *pdata = get_pdata(dssdev); | 322 | struct tfp410_platform_data *pdata = get_pdata(dssdev); |
305 | struct i2c_adapter *adapter; | 323 | struct i2c_adapter *adapter; |
306 | unsigned char out; | 324 | unsigned char out; |
307 | int r; | 325 | int r; |
@@ -315,7 +333,7 @@ static bool panel_dvi_detect(struct omap_dss_device *dssdev) | |||
315 | if (!adapter) | 333 | if (!adapter) |
316 | goto out; | 334 | goto out; |
317 | 335 | ||
318 | r = panel_dvi_ddc_read(adapter, &out, 1, 0); | 336 | r = tfp410_ddc_read(adapter, &out, 1, 0); |
319 | 337 | ||
320 | mutex_unlock(&ddata->lock); | 338 | mutex_unlock(&ddata->lock); |
321 | 339 | ||
@@ -326,38 +344,38 @@ out: | |||
326 | return true; | 344 | return true; |
327 | } | 345 | } |
328 | 346 | ||
329 | static struct omap_dss_driver panel_dvi_driver = { | 347 | static struct omap_dss_driver tfp410_driver = { |
330 | .probe = panel_dvi_probe, | 348 | .probe = tfp410_probe, |
331 | .remove = __exit_p(panel_dvi_remove), | 349 | .remove = __exit_p(tfp410_remove), |
332 | 350 | ||
333 | .enable = panel_dvi_enable, | 351 | .enable = tfp410_enable, |
334 | .disable = panel_dvi_disable, | 352 | .disable = tfp410_disable, |
335 | .suspend = panel_dvi_suspend, | 353 | .suspend = tfp410_suspend, |
336 | .resume = panel_dvi_resume, | 354 | .resume = tfp410_resume, |
337 | 355 | ||
338 | .set_timings = panel_dvi_set_timings, | 356 | .set_timings = tfp410_set_timings, |
339 | .get_timings = panel_dvi_get_timings, | 357 | .get_timings = tfp410_get_timings, |
340 | .check_timings = panel_dvi_check_timings, | 358 | .check_timings = tfp410_check_timings, |
341 | 359 | ||
342 | .read_edid = panel_dvi_read_edid, | 360 | .read_edid = tfp410_read_edid, |
343 | .detect = panel_dvi_detect, | 361 | .detect = tfp410_detect, |
344 | 362 | ||
345 | .driver = { | 363 | .driver = { |
346 | .name = "dvi", | 364 | .name = "tfp410", |
347 | .owner = THIS_MODULE, | 365 | .owner = THIS_MODULE, |
348 | }, | 366 | }, |
349 | }; | 367 | }; |
350 | 368 | ||
351 | static int __init panel_dvi_init(void) | 369 | static int __init tfp410_init(void) |
352 | { | 370 | { |
353 | return omap_dss_register_driver(&panel_dvi_driver); | 371 | return omap_dss_register_driver(&tfp410_driver); |
354 | } | 372 | } |
355 | 373 | ||
356 | static void __exit panel_dvi_exit(void) | 374 | static void __exit tfp410_exit(void) |
357 | { | 375 | { |
358 | omap_dss_unregister_driver(&panel_dvi_driver); | 376 | omap_dss_unregister_driver(&tfp410_driver); |
359 | } | 377 | } |
360 | 378 | ||
361 | module_init(panel_dvi_init); | 379 | module_init(tfp410_init); |
362 | module_exit(panel_dvi_exit); | 380 | module_exit(tfp410_exit); |
363 | MODULE_LICENSE("GPL"); | 381 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 662d14f8c2c3..210a3c4f6150 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -2076,65 +2076,6 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) | |||
2076 | } | 2076 | } |
2077 | } | 2077 | } |
2078 | 2078 | ||
2079 | static int dsi_parse_lane_config(struct omap_dss_device *dssdev) | ||
2080 | { | ||
2081 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2082 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2083 | u8 lanes[DSI_MAX_NR_LANES]; | ||
2084 | u8 polarities[DSI_MAX_NR_LANES]; | ||
2085 | int num_lanes, i; | ||
2086 | |||
2087 | static const enum dsi_lane_function functions[] = { | ||
2088 | DSI_LANE_CLK, | ||
2089 | DSI_LANE_DATA1, | ||
2090 | DSI_LANE_DATA2, | ||
2091 | DSI_LANE_DATA3, | ||
2092 | DSI_LANE_DATA4, | ||
2093 | }; | ||
2094 | |||
2095 | lanes[0] = dssdev->phy.dsi.clk_lane; | ||
2096 | lanes[1] = dssdev->phy.dsi.data1_lane; | ||
2097 | lanes[2] = dssdev->phy.dsi.data2_lane; | ||
2098 | lanes[3] = dssdev->phy.dsi.data3_lane; | ||
2099 | lanes[4] = dssdev->phy.dsi.data4_lane; | ||
2100 | polarities[0] = dssdev->phy.dsi.clk_pol; | ||
2101 | polarities[1] = dssdev->phy.dsi.data1_pol; | ||
2102 | polarities[2] = dssdev->phy.dsi.data2_pol; | ||
2103 | polarities[3] = dssdev->phy.dsi.data3_pol; | ||
2104 | polarities[4] = dssdev->phy.dsi.data4_pol; | ||
2105 | |||
2106 | num_lanes = 0; | ||
2107 | |||
2108 | for (i = 0; i < dsi->num_lanes_supported; ++i) | ||
2109 | dsi->lanes[i].function = DSI_LANE_UNUSED; | ||
2110 | |||
2111 | for (i = 0; i < dsi->num_lanes_supported; ++i) { | ||
2112 | int num; | ||
2113 | |||
2114 | if (lanes[i] == DSI_LANE_UNUSED) | ||
2115 | break; | ||
2116 | |||
2117 | num = lanes[i] - 1; | ||
2118 | |||
2119 | if (num >= dsi->num_lanes_supported) | ||
2120 | return -EINVAL; | ||
2121 | |||
2122 | if (dsi->lanes[num].function != DSI_LANE_UNUSED) | ||
2123 | return -EINVAL; | ||
2124 | |||
2125 | dsi->lanes[num].function = functions[i]; | ||
2126 | dsi->lanes[num].polarity = polarities[i]; | ||
2127 | num_lanes++; | ||
2128 | } | ||
2129 | |||
2130 | if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported) | ||
2131 | return -EINVAL; | ||
2132 | |||
2133 | dsi->num_lanes_used = num_lanes; | ||
2134 | |||
2135 | return 0; | ||
2136 | } | ||
2137 | |||
2138 | static int dsi_set_lane_config(struct omap_dss_device *dssdev) | 2079 | static int dsi_set_lane_config(struct omap_dss_device *dssdev) |
2139 | { | 2080 | { |
2140 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 2081 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -3975,6 +3916,74 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
3975 | } | 3916 | } |
3976 | } | 3917 | } |
3977 | 3918 | ||
3919 | int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev, | ||
3920 | const struct omap_dsi_pin_config *pin_cfg) | ||
3921 | { | ||
3922 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3923 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3924 | int num_pins; | ||
3925 | const int *pins; | ||
3926 | struct dsi_lane_config lanes[DSI_MAX_NR_LANES]; | ||
3927 | int num_lanes; | ||
3928 | int i; | ||
3929 | |||
3930 | static const enum dsi_lane_function functions[] = { | ||
3931 | DSI_LANE_CLK, | ||
3932 | DSI_LANE_DATA1, | ||
3933 | DSI_LANE_DATA2, | ||
3934 | DSI_LANE_DATA3, | ||
3935 | DSI_LANE_DATA4, | ||
3936 | }; | ||
3937 | |||
3938 | num_pins = pin_cfg->num_pins; | ||
3939 | pins = pin_cfg->pins; | ||
3940 | |||
3941 | if (num_pins < 4 || num_pins > dsi->num_lanes_supported * 2 | ||
3942 | || num_pins % 2 != 0) | ||
3943 | return -EINVAL; | ||
3944 | |||
3945 | for (i = 0; i < DSI_MAX_NR_LANES; ++i) | ||
3946 | lanes[i].function = DSI_LANE_UNUSED; | ||
3947 | |||
3948 | num_lanes = 0; | ||
3949 | |||
3950 | for (i = 0; i < num_pins; i += 2) { | ||
3951 | u8 lane, pol; | ||
3952 | int dx, dy; | ||
3953 | |||
3954 | dx = pins[i]; | ||
3955 | dy = pins[i + 1]; | ||
3956 | |||
3957 | if (dx < 0 || dx >= dsi->num_lanes_supported * 2) | ||
3958 | return -EINVAL; | ||
3959 | |||
3960 | if (dy < 0 || dy >= dsi->num_lanes_supported * 2) | ||
3961 | return -EINVAL; | ||
3962 | |||
3963 | if (dx & 1) { | ||
3964 | if (dy != dx - 1) | ||
3965 | return -EINVAL; | ||
3966 | pol = 1; | ||
3967 | } else { | ||
3968 | if (dy != dx + 1) | ||
3969 | return -EINVAL; | ||
3970 | pol = 0; | ||
3971 | } | ||
3972 | |||
3973 | lane = dx / 2; | ||
3974 | |||
3975 | lanes[lane].function = functions[i / 2]; | ||
3976 | lanes[lane].polarity = pol; | ||
3977 | num_lanes++; | ||
3978 | } | ||
3979 | |||
3980 | memcpy(dsi->lanes, lanes, sizeof(dsi->lanes)); | ||
3981 | dsi->num_lanes_used = num_lanes; | ||
3982 | |||
3983 | return 0; | ||
3984 | } | ||
3985 | EXPORT_SYMBOL(omapdss_dsi_configure_pins); | ||
3986 | |||
3978 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) | 3987 | int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) |
3979 | { | 3988 | { |
3980 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | 3989 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
@@ -4339,12 +4348,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
4339 | int dsi_module = dsi_get_dsidev_id(dsidev); | 4348 | int dsi_module = dsi_get_dsidev_id(dsidev); |
4340 | int r; | 4349 | int r; |
4341 | 4350 | ||
4342 | r = dsi_parse_lane_config(dssdev); | ||
4343 | if (r) { | ||
4344 | DSSERR("illegal lane config"); | ||
4345 | goto err0; | ||
4346 | } | ||
4347 | |||
4348 | r = dsi_pll_init(dsidev, true, true); | 4351 | r = dsi_pll_init(dsidev, true, true); |
4349 | if (r) | 4352 | if (r) |
4350 | goto err0; | 4353 | goto err0; |