diff options
Diffstat (limited to 'recipes-bsp/barebox/barebox-2012.02.0/imx53qsb/0002-mfd-add-mc34708-driver.patch')
-rw-r--r-- | recipes-bsp/barebox/barebox-2012.02.0/imx53qsb/0002-mfd-add-mc34708-driver.patch | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/recipes-bsp/barebox/barebox-2012.02.0/imx53qsb/0002-mfd-add-mc34708-driver.patch b/recipes-bsp/barebox/barebox-2012.02.0/imx53qsb/0002-mfd-add-mc34708-driver.patch new file mode 100644 index 0000000..a494d63 --- /dev/null +++ b/recipes-bsp/barebox/barebox-2012.02.0/imx53qsb/0002-mfd-add-mc34708-driver.patch | |||
@@ -0,0 +1,459 @@ | |||
1 | From cafc72b3292a6820a01b6c5baed4c821ba2e62e7 Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Eric=20B=C3=A9nard?= <eric@eukrea.com> | ||
3 | Date: Tue, 21 Feb 2012 01:00:29 +0100 | ||
4 | Subject: [PATCH 2/7] mfd: add mc34708 driver | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | this driver is a copie of the mc13892 one | ||
10 | |||
11 | Signed-off-by: Eric Bénard <eric@eukrea.com> | ||
12 | --- | ||
13 | Upstream-Status: Applied for 2012.04.0 | ||
14 | |||
15 | drivers/mfd/Kconfig | 4 + | ||
16 | drivers/mfd/Makefile | 1 + | ||
17 | drivers/mfd/mc34708.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++ | ||
18 | include/mfd/mc34708.h | 102 +++++++++++++++++ | ||
19 | 4 files changed, 401 insertions(+), 0 deletions(-) | ||
20 | create mode 100644 drivers/mfd/mc34708.c | ||
21 | create mode 100644 include/mfd/mc34708.h | ||
22 | |||
23 | diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig | ||
24 | index 87797de..b080c1c 100644 | ||
25 | --- a/drivers/mfd/Kconfig | ||
26 | +++ b/drivers/mfd/Kconfig | ||
27 | @@ -8,6 +8,10 @@ config I2C_MC34704 | ||
28 | depends on I2C | ||
29 | bool "MC34704 PMIC driver" | ||
30 | |||
31 | +config I2C_MC34708 | ||
32 | + depends on I2C | ||
33 | + bool "MC34708 PMIC driver" | ||
34 | + | ||
35 | config I2C_MC9SDZ60 | ||
36 | depends on I2C | ||
37 | bool "MC9SDZ60 driver" | ||
38 | diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile | ||
39 | index 1171335..bc9e0e8 100644 | ||
40 | --- a/drivers/mfd/Makefile | ||
41 | +++ b/drivers/mfd/Makefile | ||
42 | @@ -1,5 +1,6 @@ | ||
43 | obj-$(CONFIG_I2C_MC13892) += mc13892.o | ||
44 | obj-$(CONFIG_I2C_MC34704) += mc34704.o | ||
45 | +obj-$(CONFIG_I2C_MC34708) += mc34708.o | ||
46 | obj-$(CONFIG_I2C_MC9SDZ60) += mc9sdz60.o | ||
47 | obj-$(CONFIG_I2C_LP3972) += lp3972.o | ||
48 | obj-$(CONFIG_I2C_TWLCORE) += twl-core.o | ||
49 | diff --git a/drivers/mfd/mc34708.c b/drivers/mfd/mc34708.c | ||
50 | new file mode 100644 | ||
51 | index 0000000..e7f40c0 | ||
52 | --- /dev/null | ||
53 | +++ b/drivers/mfd/mc34708.c | ||
54 | @@ -0,0 +1,294 @@ | ||
55 | +/* | ||
56 | + * Copyright (C) 2007 Sascha Hauer, Pengutronix | ||
57 | + * 2009 Marc Kleine-Budde <mkl@pengutronix.de> | ||
58 | + * | ||
59 | + * This program is free software; you can redistribute it and/or | ||
60 | + * modify it under the terms of the GNU General Public License as | ||
61 | + * published by the Free Software Foundation; either version 2 of | ||
62 | + * the License, or (at your option) any later version. | ||
63 | + * | ||
64 | + * This program is distributed in the hope that it will be useful, | ||
65 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
66 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
67 | + * GNU General Public License for more details. | ||
68 | + * | ||
69 | + * You should have received a copy of the GNU General Public License | ||
70 | + * along with this program; if not, write to the Free Software | ||
71 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
72 | + * MA 02111-1307 USA | ||
73 | + * | ||
74 | + */ | ||
75 | + | ||
76 | +#include <common.h> | ||
77 | +#include <init.h> | ||
78 | +#include <driver.h> | ||
79 | +#include <xfuncs.h> | ||
80 | +#include <errno.h> | ||
81 | +#include <spi/spi.h> | ||
82 | +#include <malloc.h> | ||
83 | + | ||
84 | +#include <i2c/i2c.h> | ||
85 | +#include <mfd/mc34708.h> | ||
86 | + | ||
87 | +#define DRIVERNAME "mc34708" | ||
88 | + | ||
89 | +#define to_mc34708(a) container_of(a, struct mc34708, cdev) | ||
90 | + | ||
91 | +static struct mc34708 *mc_dev; | ||
92 | + | ||
93 | +struct mc34708 *mc34708_get(void) | ||
94 | +{ | ||
95 | + if (!mc_dev) | ||
96 | + return NULL; | ||
97 | + | ||
98 | + return mc_dev; | ||
99 | +} | ||
100 | +EXPORT_SYMBOL(mc34708_get); | ||
101 | + | ||
102 | +#ifdef CONFIG_SPI | ||
103 | +static int spi_rw(struct spi_device *spi, void * buf, size_t len) | ||
104 | +{ | ||
105 | + int ret; | ||
106 | + | ||
107 | + struct spi_transfer t = { | ||
108 | + .tx_buf = (const void *)buf, | ||
109 | + .rx_buf = buf, | ||
110 | + .len = len, | ||
111 | + .cs_change = 0, | ||
112 | + .delay_usecs = 0, | ||
113 | + }; | ||
114 | + struct spi_message m; | ||
115 | + | ||
116 | + spi_message_init(&m); | ||
117 | + spi_message_add_tail(&t, &m); | ||
118 | + | ||
119 | + if ((ret = spi_sync(spi, &m))) | ||
120 | + return ret; | ||
121 | + return 0; | ||
122 | +} | ||
123 | + | ||
124 | +#define MXC_PMIC_REG_NUM(reg) (((reg) & 0x3f) << 25) | ||
125 | +#define MXC_PMIC_WRITE (1 << 31) | ||
126 | + | ||
127 | +static int mc34708_spi_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val) | ||
128 | +{ | ||
129 | + uint32_t buf; | ||
130 | + | ||
131 | + buf = MXC_PMIC_REG_NUM(reg); | ||
132 | + | ||
133 | + spi_rw(mc34708->spi, &buf, 4); | ||
134 | + | ||
135 | + *val = buf; | ||
136 | + | ||
137 | + return 0; | ||
138 | +} | ||
139 | + | ||
140 | +static int mc34708_spi_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val) | ||
141 | +{ | ||
142 | + uint32_t buf = MXC_PMIC_REG_NUM(reg) | MXC_PMIC_WRITE | (val & 0xffffff); | ||
143 | + | ||
144 | + spi_rw(mc34708->spi, &buf, 4); | ||
145 | + | ||
146 | + return 0; | ||
147 | +} | ||
148 | +#endif | ||
149 | + | ||
150 | +#ifdef CONFIG_I2C | ||
151 | +static int mc34708_i2c_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val) | ||
152 | +{ | ||
153 | + u8 buf[3]; | ||
154 | + int ret; | ||
155 | + | ||
156 | + ret = i2c_read_reg(mc34708->client, reg, buf, 3); | ||
157 | + *val = buf[0] << 16 | buf[1] << 8 | buf[2] << 0; | ||
158 | + | ||
159 | + return ret == 3 ? 0 : ret; | ||
160 | +} | ||
161 | + | ||
162 | +static int mc34708_i2c_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val) | ||
163 | +{ | ||
164 | + u8 buf[] = { | ||
165 | + val >> 16, | ||
166 | + val >> 8, | ||
167 | + val >> 0, | ||
168 | + }; | ||
169 | + int ret; | ||
170 | + | ||
171 | + ret = i2c_write_reg(mc34708->client, reg, buf, 3); | ||
172 | + | ||
173 | + return ret == 3 ? 0 : ret; | ||
174 | +} | ||
175 | +#endif | ||
176 | + | ||
177 | +int mc34708_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val) | ||
178 | +{ | ||
179 | +#ifdef CONFIG_I2C | ||
180 | + if (mc34708->mode == MC34708_MODE_I2C) | ||
181 | + return mc34708_i2c_reg_write(mc34708, reg, val); | ||
182 | +#endif | ||
183 | +#ifdef CONFIG_SPI | ||
184 | + if (mc34708->mode == MC34708_MODE_SPI) | ||
185 | + return mc34708_spi_reg_write(mc34708, reg, val); | ||
186 | +#endif | ||
187 | + return -EINVAL; | ||
188 | +} | ||
189 | +EXPORT_SYMBOL(mc34708_reg_write); | ||
190 | + | ||
191 | +int mc34708_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val) | ||
192 | +{ | ||
193 | +#ifdef CONFIG_I2C | ||
194 | + if (mc34708->mode == MC34708_MODE_I2C) | ||
195 | + return mc34708_i2c_reg_read(mc34708, reg, val); | ||
196 | +#endif | ||
197 | +#ifdef CONFIG_SPI | ||
198 | + if (mc34708->mode == MC34708_MODE_SPI) | ||
199 | + return mc34708_spi_reg_read(mc34708, reg, val); | ||
200 | +#endif | ||
201 | + return -EINVAL; | ||
202 | +} | ||
203 | +EXPORT_SYMBOL(mc34708_reg_read); | ||
204 | + | ||
205 | +int mc34708_set_bits(struct mc34708 *mc34708, enum mc34708_reg reg, u32 mask, u32 val) | ||
206 | +{ | ||
207 | + u32 tmp; | ||
208 | + int err; | ||
209 | + | ||
210 | + err = mc34708_reg_read(mc34708, reg, &tmp); | ||
211 | + tmp = (tmp & ~mask) | val; | ||
212 | + | ||
213 | + if (!err) | ||
214 | + err = mc34708_reg_write(mc34708, reg, tmp); | ||
215 | + | ||
216 | + return err; | ||
217 | +} | ||
218 | +EXPORT_SYMBOL(mc34708_set_bits); | ||
219 | + | ||
220 | +static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) | ||
221 | +{ | ||
222 | + struct mc34708 *priv = to_mc34708(cdev); | ||
223 | + u32 *buf = _buf; | ||
224 | + size_t i = count >> 2; | ||
225 | + int err; | ||
226 | + | ||
227 | + offset >>= 2; | ||
228 | + | ||
229 | + while (i) { | ||
230 | + err = mc34708_reg_read(priv, offset, buf); | ||
231 | + if (err) | ||
232 | + return (ssize_t)err; | ||
233 | + buf++; | ||
234 | + i--; | ||
235 | + offset++; | ||
236 | + } | ||
237 | + | ||
238 | + return count; | ||
239 | +} | ||
240 | + | ||
241 | +static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags) | ||
242 | +{ | ||
243 | + struct mc34708 *mc34708 = to_mc34708(cdev); | ||
244 | + const u32 *buf = _buf; | ||
245 | + size_t i = count >> 2; | ||
246 | + int err; | ||
247 | + | ||
248 | + offset >>= 2; | ||
249 | + | ||
250 | + while (i) { | ||
251 | + err = mc34708_reg_write(mc34708, offset, *buf); | ||
252 | + if (err) | ||
253 | + return (ssize_t)err; | ||
254 | + buf++; | ||
255 | + i--; | ||
256 | + offset++; | ||
257 | + } | ||
258 | + | ||
259 | + return count; | ||
260 | +} | ||
261 | + | ||
262 | +static struct file_operations mc_fops = { | ||
263 | + .lseek = dev_lseek_default, | ||
264 | + .read = mc_read, | ||
265 | + .write = mc_write, | ||
266 | +}; | ||
267 | + | ||
268 | +static int mc34708_query_revision(struct mc34708 *mc34708) | ||
269 | +{ | ||
270 | + unsigned int rev_id; | ||
271 | + int rev; | ||
272 | + | ||
273 | + mc34708_reg_read(mc34708, 7, &rev_id); | ||
274 | + | ||
275 | + if (rev_id > 0xFFF) | ||
276 | + return -EINVAL; | ||
277 | + | ||
278 | + rev = rev_id & 0xFFF; | ||
279 | + | ||
280 | + dev_info(mc_dev->cdev.dev, "MC34708 ID: 0x%04x\n", rev); | ||
281 | + | ||
282 | + mc34708->revision = rev; | ||
283 | + | ||
284 | + return rev; | ||
285 | +} | ||
286 | + | ||
287 | +static int mc_probe(struct device_d *dev, enum mc34708_mode mode) | ||
288 | +{ | ||
289 | + int rev; | ||
290 | + | ||
291 | + if (mc_dev) | ||
292 | + return -EBUSY; | ||
293 | + | ||
294 | + mc_dev = xzalloc(sizeof(struct mc34708)); | ||
295 | + mc_dev->mode = mode; | ||
296 | + mc_dev->cdev.name = DRIVERNAME; | ||
297 | + if (mode == MC34708_MODE_I2C) { | ||
298 | + mc_dev->client = to_i2c_client(dev); | ||
299 | + } | ||
300 | + if (mode == MC34708_MODE_SPI) { | ||
301 | + mc_dev->spi = dev->type_data; | ||
302 | + mc_dev->spi->mode = SPI_MODE_0 | SPI_CS_HIGH; | ||
303 | + mc_dev->spi->bits_per_word = 32; | ||
304 | + } | ||
305 | + mc_dev->cdev.size = 256; | ||
306 | + mc_dev->cdev.dev = dev; | ||
307 | + mc_dev->cdev.ops = &mc_fops; | ||
308 | + | ||
309 | + rev = mc34708_query_revision(mc_dev); | ||
310 | + if (rev < 0) { | ||
311 | + free(mc_dev); | ||
312 | + mc_dev = NULL; | ||
313 | + return -EINVAL; | ||
314 | + } | ||
315 | + | ||
316 | + devfs_create(&mc_dev->cdev); | ||
317 | + | ||
318 | + return 0; | ||
319 | +} | ||
320 | + | ||
321 | +static int mc_i2c_probe(struct device_d *dev) | ||
322 | +{ | ||
323 | + return mc_probe(dev, MC34708_MODE_I2C); | ||
324 | +} | ||
325 | + | ||
326 | +static int mc_spi_probe(struct device_d *dev) | ||
327 | +{ | ||
328 | + return mc_probe(dev, MC34708_MODE_SPI); | ||
329 | +} | ||
330 | + | ||
331 | +static struct driver_d mc_i2c_driver = { | ||
332 | + .name = "mc34708-i2c", | ||
333 | + .probe = mc_i2c_probe, | ||
334 | +}; | ||
335 | + | ||
336 | +static struct driver_d mc_spi_driver = { | ||
337 | + .name = "mc34708-spi", | ||
338 | + .probe = mc_spi_probe, | ||
339 | +}; | ||
340 | + | ||
341 | +static int mc_init(void) | ||
342 | +{ | ||
343 | + register_driver(&mc_i2c_driver); | ||
344 | + register_driver(&mc_spi_driver); | ||
345 | + return 0; | ||
346 | +} | ||
347 | + | ||
348 | +device_initcall(mc_init); | ||
349 | diff --git a/include/mfd/mc34708.h b/include/mfd/mc34708.h | ||
350 | new file mode 100644 | ||
351 | index 0000000..f384c62 | ||
352 | --- /dev/null | ||
353 | +++ b/include/mfd/mc34708.h | ||
354 | @@ -0,0 +1,102 @@ | ||
355 | +/* | ||
356 | + * Copyright (C) 2009 Marc Kleine-Budde <mkl@pengutronix.de> | ||
357 | + * | ||
358 | + * This file is released under the GPLv2 | ||
359 | + * | ||
360 | + * Derived from: | ||
361 | + * - arch-mxc/pmic_external.h -- contains interface of the PMIC protocol driver | ||
362 | + * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. | ||
363 | + * | ||
364 | + */ | ||
365 | + | ||
366 | +#ifndef __ASM_ARCH_MC34708_H | ||
367 | +#define __ASM_ARCH_MC34708_H | ||
368 | + | ||
369 | +enum mc34708_reg { | ||
370 | + MC34708_REG_INT_STATUS0 = 0x00, | ||
371 | + MC34708_REG_INT_MASK0 = 0x01, | ||
372 | + MC34708_REG_INT_SENSE0 = 0x02, | ||
373 | + MC34708_REG_INT_STATUS1 = 0x03, | ||
374 | + MC34708_REG_INT_MASK1 = 0x04, | ||
375 | + MC34708_REG_INT_SENSE1 = 0x05, | ||
376 | + MC34708_REG_PU_MODE_S = 0x06, | ||
377 | + MC34708_REG_IDENTIFICATION = 0x07, | ||
378 | + MC34708_REG_REG_FAULT_S = 0x08, | ||
379 | + MC34708_REG_ACC0 = 0x09, | ||
380 | + MC34708_REG_ACC1 = 0x0a, | ||
381 | + MC34708_REG_ACC2 = 0x0b, | ||
382 | + MC34708_REG_UNUSED0 = 0x0c, | ||
383 | + MC34708_REG_POWER_CTL0 = 0x0d, | ||
384 | + MC34708_REG_POWER_CTL1 = 0x0e, | ||
385 | + MC34708_REG_POWER_CTL2 = 0x0f, | ||
386 | + MC34708_REG_MEM_A = 0x10, | ||
387 | + MC34708_REG_MEM_B = 0x11, | ||
388 | + MC34708_REG_MEM_C = 0x12, | ||
389 | + MC34708_REG_MEM_D = 0x13, | ||
390 | + MC34708_REG_RTC_TIME = 0x14, | ||
391 | + MC34708_REG_RTC_ALARM = 0x15, | ||
392 | + MC34708_REG_RTC_DAY = 0x16, | ||
393 | + MC34708_REG_RTC_DAY_ALARM = 0x17, | ||
394 | + MC34708_REG_1 = 0x18, | ||
395 | + MC34708_REG_2_3 = 0x19, | ||
396 | + MC34708_REG_4 = 0x1a, | ||
397 | + MC34708_REG_5 = 0x1b, | ||
398 | + MC34708_REG_1_2_MODE = 0x1c, | ||
399 | + MC34708_REG_3_4_5_MODE = 0x1d, | ||
400 | + MC34708_REG_SETTING_0 = 0x1e, | ||
401 | + MC34708_REG_SWBST_CTRL = 0x1f, | ||
402 | + MC34708_REG_MODE_0 = 0x20, | ||
403 | + MC34708_REG_GPIOLV0_CTRL = 0x21, | ||
404 | + MC34708_REG_GPIOLV1_CTRL = 0x22, | ||
405 | + MC34708_REG_GPIOLV2_CTRL = 0x23, | ||
406 | + MC34708_REG_GPIOLV3_CTRL = 0x24, | ||
407 | + MC34708_REG_USB_TIMING = 0x25, | ||
408 | + MC34708_REG_USB_BUTTON = 0x26, | ||
409 | + MC34708_REG_USB_CTRL = 0x27, | ||
410 | + MC34708_REG_USB_DEVTYPE = 0x28, | ||
411 | + MC34708_REG_UNUSED1 = 0x29, | ||
412 | + MC34708_REG_UNUSED2 = 0x2a, | ||
413 | + MC34708_REG_ADC0 = 0x2b, | ||
414 | + MC34708_REG_ADC1 = 0x2c, | ||
415 | + MC34708_REG_ADC2 = 0x2d, | ||
416 | + MC34708_REG_ADC3 = 0x2e, | ||
417 | + MC34708_REG_ADC4 = 0x2f, | ||
418 | + MC34708_REG_ADC5 = 0x30, | ||
419 | + MC34708_REG_ADC6 = 0x31, | ||
420 | + MC34708_REG_ADC7 = 0x32, | ||
421 | + MC34708_REG_BAT_PROFILE = 0x33, | ||
422 | + MC34708_REG_CHRG_DEBOUNCE = 0x34, | ||
423 | + MC34708_REG_CHRG_SOURCE = 0x35, | ||
424 | + MC34708_REG_CHRG_LED_CTRL = 0x36, | ||
425 | + MC34708_REG_PWM_CTRL = 0x37, | ||
426 | + MC34708_REG_UNUSED3 = 0x38, | ||
427 | + MC34708_REG_UNUSED4 = 0x39, | ||
428 | + MC34708_REG_UNUSED5 = 0x3a, | ||
429 | + MC34708_REG_UNUSED6 = 0x3b, | ||
430 | + MC34708_REG_UNUSED7 = 0x3c, | ||
431 | + MC34708_REG_UNUSED8 = 0x3d, | ||
432 | + MC34708_REG_UNUSED9 = 0x3e, | ||
433 | + MC34708_REG_UNUSED10 = 0x3f, | ||
434 | +}; | ||
435 | + | ||
436 | + | ||
437 | +enum mc34708_mode { | ||
438 | + MC34708_MODE_I2C, | ||
439 | + MC34708_MODE_SPI, | ||
440 | +}; | ||
441 | + | ||
442 | +struct mc34708 { | ||
443 | + struct cdev cdev; | ||
444 | + struct i2c_client *client; | ||
445 | + struct spi_device *spi; | ||
446 | + enum mc34708_mode mode; | ||
447 | + unsigned int revision; | ||
448 | +}; | ||
449 | + | ||
450 | +extern struct mc34708 *mc34708_get(void); | ||
451 | + | ||
452 | +extern int mc34708_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val); | ||
453 | +extern int mc34708_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val); | ||
454 | +extern int mc34708_set_bits(struct mc34708 *mc34708, enum mc34708_reg reg, u32 mask, u32 val); | ||
455 | + | ||
456 | +#endif /* __ASM_ARCH_MC34708_H */ | ||
457 | -- | ||
458 | 1.7.7.6 | ||
459 | |||