summaryrefslogtreecommitdiffstats
path: root/recipes-bsp/barebox/barebox-2012.02.0/imx53qsb/0002-mfd-add-mc34708-driver.patch
diff options
context:
space:
mode:
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.patch459
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 @@
1From cafc72b3292a6820a01b6c5baed4c821ba2e62e7 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Eric=20B=C3=A9nard?= <eric@eukrea.com>
3Date: Tue, 21 Feb 2012 01:00:29 +0100
4Subject: [PATCH 2/7] mfd: add mc34708 driver
5MIME-Version: 1.0
6Content-Type: text/plain; charset=UTF-8
7Content-Transfer-Encoding: 8bit
8
9this driver is a copie of the mc13892 one
10
11Signed-off-by: Eric Bénard <eric@eukrea.com>
12---
13Upstream-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
23diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
24index 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"
38diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
39index 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
49diff --git a/drivers/mfd/mc34708.c b/drivers/mfd/mc34708.c
50new file mode 100644
51index 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);
349diff --git a/include/mfd/mc34708.h b/include/mfd/mc34708.h
350new file mode 100644
351index 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--
4581.7.7.6
459