blob: fa7c1160e44d85f615216dcefb9e2585de75565d [file] [log] [blame]
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
Kiran Kandi725f8492012-08-06 13:45:16 -070015#include <linux/of_gpio.h>
Joonwoo Parkf6574c72012-10-10 17:29:57 -070016#include <linux/of_irq.h>
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053017#include <linux/slab.h>
18#include <linux/mfd/core.h>
19#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
20#include <linux/mfd/wcd9xxx/core.h>
21#include <linux/mfd/wcd9xxx/pdata.h>
22#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
23
24#include <linux/delay.h>
25#include <linux/gpio.h>
26#include <linux/debugfs.h>
27#include <linux/regulator/consumer.h>
28#include <linux/i2c.h>
29#include <sound/soc.h>
30
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053031#define WCD9XXX_REGISTER_START_OFFSET 0x800
32#define WCD9XXX_SLIM_RW_MAX_TRIES 3
Joonwoo Park3c5b2df2012-08-28 15:36:55 -070033#define SLIMBUS_PRESENT_TIMEOUT 100
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053034
35#define MAX_WCD9XXX_DEVICE 4
Asish Bhattacharya2b709d42011-11-15 10:39:23 +053036#define TABLA_I2C_MODE 0x03
37#define SITAR_I2C_MODE 0x01
Venkat Sudhira41630a2012-10-27 00:57:31 -070038#define CODEC_DT_MAX_PROP_SIZE 40
39#define WCD9XXX_I2C_GSBI_SLAVE_ID "3-000d"
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053040
41struct wcd9xxx_i2c {
42 struct i2c_client *client;
43 struct i2c_msg xfer_msg[2];
44 struct mutex xfer_lock;
45 int mod_id;
46};
47
Venkat Sudhira41630a2012-10-27 00:57:31 -070048static char *taiko_supplies[] = {
49 "cdc-vdd-buck", "cdc-vdd-tx-h", "cdc-vdd-rx-h", "cdc-vddpx-1",
50 "cdc-vdd-a-1p2v", "cdc-vddcx-1", "cdc-vddcx-2",
51};
52
53static int wcd9xxx_dt_parse_vreg_info(struct device *dev,
54 struct wcd9xxx_regulator *vreg, const char *vreg_name);
55static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
56 struct wcd9xxx_micbias_setting *micbias);
57static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev);
58
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053059struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -070060static int wcd9xxx_intf = -1;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053061
62static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
63 int bytes, void *dest, bool interface_reg)
64{
65 int ret;
66 u8 *buf = dest;
67
68 if (bytes <= 0) {
69 dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
70 return -EINVAL;
71 }
72
73 ret = wcd9xxx->read_dev(wcd9xxx, reg, bytes, dest, interface_reg);
74 if (ret < 0) {
75 dev_err(wcd9xxx->dev, "Codec read failed\n");
76 return ret;
77 } else
Kiran Kandi1e6371d2012-03-29 11:48:57 -070078 dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
79 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053080
81 return 0;
82}
83int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
84{
85 u8 val;
86 int ret;
87
88 mutex_lock(&wcd9xxx->io_lock);
89 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false);
90 mutex_unlock(&wcd9xxx->io_lock);
91
92 if (ret < 0)
93 return ret;
94 else
95 return val;
96}
97EXPORT_SYMBOL_GPL(wcd9xxx_reg_read);
98
99static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
100 int bytes, void *src, bool interface_reg)
101{
102 u8 *buf = src;
103
104 if (bytes <= 0) {
105 pr_err("%s: Error, invalid write length\n", __func__);
106 return -EINVAL;
107 }
108
Kiran Kandi1e6371d2012-03-29 11:48:57 -0700109 dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n",
110 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530111
112 return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
113}
114
115int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
116 u8 val)
117{
118 int ret;
119
120 mutex_lock(&wcd9xxx->io_lock);
121 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, false);
122 mutex_unlock(&wcd9xxx->io_lock);
123
124 return ret;
125}
126EXPORT_SYMBOL_GPL(wcd9xxx_reg_write);
127
128static u8 wcd9xxx_pgd_la;
129static u8 wcd9xxx_inf_la;
130
131int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
132{
133 u8 val;
134 int ret;
135
136 mutex_lock(&wcd9xxx->io_lock);
137 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, true);
138 mutex_unlock(&wcd9xxx->io_lock);
139
140 if (ret < 0)
141 return ret;
142 else
143 return val;
144}
145EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_read);
146
147int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
148 u8 val)
149{
150 int ret;
151
152 mutex_lock(&wcd9xxx->io_lock);
153 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, true);
154 mutex_unlock(&wcd9xxx->io_lock);
155
156 return ret;
157}
158EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_write);
159
160int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
161 int count, u8 *buf)
162{
163 int ret;
164
165 mutex_lock(&wcd9xxx->io_lock);
166
167 ret = wcd9xxx_read(wcd9xxx, reg, count, buf, false);
168
169 mutex_unlock(&wcd9xxx->io_lock);
170
171 return ret;
172}
173EXPORT_SYMBOL_GPL(wcd9xxx_bulk_read);
174
175int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
176 int count, u8 *buf)
177{
178 int ret;
179
180 mutex_lock(&wcd9xxx->io_lock);
181
182 ret = wcd9xxx_write(wcd9xxx, reg, count, buf, false);
183
184 mutex_unlock(&wcd9xxx->io_lock);
185
186 return ret;
187}
188EXPORT_SYMBOL_GPL(wcd9xxx_bulk_write);
189
190static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
191 int bytes, void *dest, bool interface)
192{
193 int ret;
194 struct slim_ele_access msg;
195 int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
196 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
197 msg.num_bytes = bytes;
198 msg.comp = NULL;
199
200 while (1) {
201 mutex_lock(&wcd9xxx->xfer_lock);
202 ret = slim_request_val_element(interface ?
203 wcd9xxx->slim_slave : wcd9xxx->slim,
204 &msg, dest, bytes);
205 mutex_unlock(&wcd9xxx->xfer_lock);
206 if (likely(ret == 0) || (--slim_read_tries == 0))
207 break;
208 usleep_range(5000, 5000);
209 }
210
211 if (ret)
212 pr_err("%s: Error, Codec read failed (%d)\n", __func__, ret);
213
214 return ret;
215}
216/* Interface specifies whether the write is to the interface or general
217 * registers.
218 */
219static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
220 unsigned short reg, int bytes, void *src, bool interface)
221{
222 int ret;
223 struct slim_ele_access msg;
224 int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
225 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
226 msg.num_bytes = bytes;
227 msg.comp = NULL;
228
229 while (1) {
230 mutex_lock(&wcd9xxx->xfer_lock);
231 ret = slim_change_val_element(interface ?
232 wcd9xxx->slim_slave : wcd9xxx->slim,
233 &msg, src, bytes);
234 mutex_unlock(&wcd9xxx->xfer_lock);
235 if (likely(ret == 0) || (--slim_write_tries == 0))
236 break;
237 usleep_range(5000, 5000);
238 }
239
240 if (ret)
241 pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
242
243 return ret;
244}
245
246static struct mfd_cell tabla1x_devs[] = {
247 {
248 .name = "tabla1x_codec",
249 },
250};
251
252static struct mfd_cell tabla_devs[] = {
253 {
254 .name = "tabla_codec",
255 },
256};
257
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530258static struct mfd_cell sitar_devs[] = {
259 {
260 .name = "sitar_codec",
261 },
262};
263
Joonwoo Parka7172112012-07-23 16:03:49 -0700264static struct mfd_cell taiko_devs[] = {
265 {
266 .name = "taiko_codec",
267 },
268};
269
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700270static struct wcd9xx_codec_type {
271 u8 byte[4];
272 struct mfd_cell *dev;
273 int size;
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700274 int num_irqs;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700275} wcd9xxx_codecs[] = {
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700276 {{0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs),
277 TABLA_NUM_IRQS},
278 {{0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs),
279 TABLA_NUM_IRQS},
280 {{0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs),
281 TAIKO_NUM_IRQS},
282 {{0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
283 SITAR_NUM_IRQS},
284 {{0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
285 SITAR_NUM_IRQS},
286 {{0x2, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs),
287 SITAR_NUM_IRQS},
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700288};
289
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530290static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
291{
292 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
293 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 0);
294 usleep_range(5000, 5000);
295 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3);
296 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3);
297}
298
299static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx)
300{
301 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x7);
302 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x6);
303 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0xe);
304 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x8);
305}
306
307static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
308{
309 int ret;
310
311 if (wcd9xxx->reset_gpio) {
312 ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
313 if (ret) {
314 pr_err("%s: Failed to request gpio %d\n", __func__,
315 wcd9xxx->reset_gpio);
316 wcd9xxx->reset_gpio = 0;
317 return ret;
318 }
319
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530320 gpio_direction_output(wcd9xxx->reset_gpio, 0);
321 msleep(20);
322 gpio_direction_output(wcd9xxx->reset_gpio, 1);
323 msleep(20);
324 }
325 return 0;
326}
327
328static void wcd9xxx_free_reset(struct wcd9xxx *wcd9xxx)
329{
330 if (wcd9xxx->reset_gpio) {
331 gpio_free(wcd9xxx->reset_gpio);
332 wcd9xxx->reset_gpio = 0;
333 }
334}
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700335static int wcd9xxx_check_codec_type(struct wcd9xxx *wcd9xxx,
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700336 struct mfd_cell **wcd9xxx_dev,
337 int *wcd9xxx_dev_size,
338 int *wcd9xxx_dev_num_irqs)
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700339{
Venkat Sudhir4414deb2012-10-01 16:26:03 -0700340 int i;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700341 int ret;
Venkat Sudhir4414deb2012-10-01 16:26:03 -0700342 i = WCD9XXX_A_CHIP_ID_BYTE_0;
343 while (i <= WCD9XXX_A_CHIP_ID_BYTE_3) {
344 ret = wcd9xxx_reg_read(wcd9xxx, i);
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700345 if (ret < 0)
346 goto exit;
Venkat Sudhir4414deb2012-10-01 16:26:03 -0700347 wcd9xxx->idbyte[i-WCD9XXX_A_CHIP_ID_BYTE_0] = (u8)ret;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700348 pr_debug("%s: wcd9xx read = %x, byte = %x\n", __func__, ret,
Venkat Sudhir4414deb2012-10-01 16:26:03 -0700349 i);
350 i++;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700351 }
352
353 /* Read codec version */
354 ret = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_VERSION);
355 if (ret < 0)
356 goto exit;
357 wcd9xxx->version = (u8)ret & 0x1F;
Venkat Sudhir4414deb2012-10-01 16:26:03 -0700358 i = 0;
359 while (i < ARRAY_SIZE(wcd9xxx_codecs)) {
360 if ((wcd9xxx_codecs[i].byte[0] == wcd9xxx->idbyte[0]) &&
361 (wcd9xxx_codecs[i].byte[1] == wcd9xxx->idbyte[1]) &&
362 (wcd9xxx_codecs[i].byte[2] == wcd9xxx->idbyte[2]) &&
363 (wcd9xxx_codecs[i].byte[3] == wcd9xxx->idbyte[3])) {
364 pr_info("%s: codec is %s", __func__,
365 wcd9xxx_codecs[i].dev->name);
366 *wcd9xxx_dev = wcd9xxx_codecs[i].dev;
367 *wcd9xxx_dev_size = wcd9xxx_codecs[i].size;
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700368 *wcd9xxx_dev_num_irqs = wcd9xxx_codecs[i].num_irqs;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700369 break;
370 }
Venkat Sudhir4414deb2012-10-01 16:26:03 -0700371 i++;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700372 }
373 if (*wcd9xxx_dev == NULL || *wcd9xxx_dev_size == 0)
374 ret = -ENODEV;
375 pr_info("%s: Read codec idbytes & version\n"
376 "byte_0[%08x] byte_1[%08x] byte_2[%08x]\n"
377 " byte_3[%08x] version = %x\n", __func__,
378 wcd9xxx->idbyte[0], wcd9xxx->idbyte[1],
379 wcd9xxx->idbyte[2], wcd9xxx->idbyte[3],
380 wcd9xxx->version);
381exit:
382 return ret;
383}
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530384
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700385static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530386{
387 int ret;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530388 struct mfd_cell *wcd9xxx_dev = NULL;
389 int wcd9xxx_dev_size = 0;
390
391 mutex_init(&wcd9xxx->io_lock);
392 mutex_init(&wcd9xxx->xfer_lock);
393
394 mutex_init(&wcd9xxx->pm_lock);
395 wcd9xxx->wlock_holders = 0;
396 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
397 init_waitqueue_head(&wcd9xxx->pm_wq);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700398 pm_qos_add_request(&wcd9xxx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
399 PM_QOS_DEFAULT_VALUE);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530400
401 dev_set_drvdata(wcd9xxx->dev, wcd9xxx);
402
403 wcd9xxx_bring_up(wcd9xxx);
404
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700405 ret = wcd9xxx_check_codec_type(wcd9xxx, &wcd9xxx_dev, &wcd9xxx_dev_size,
406 &wcd9xxx->num_irqs);
407 if (ret < 0)
408 goto err_irq;
409
Kiran Kandi725f8492012-08-06 13:45:16 -0700410 if (wcd9xxx->irq != -1) {
411 ret = wcd9xxx_irq_init(wcd9xxx);
412 if (ret) {
413 pr_err("IRQ initialization failed\n");
414 goto err;
415 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530416 }
417
Joonwoo Parka7172112012-07-23 16:03:49 -0700418 ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx_dev, wcd9xxx_dev_size,
419 NULL, 0);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530420 if (ret != 0) {
421 dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
422 goto err_irq;
423 }
424 return ret;
425err_irq:
426 wcd9xxx_irq_exit(wcd9xxx);
427err:
428 wcd9xxx_bring_down(wcd9xxx);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700429 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530430 mutex_destroy(&wcd9xxx->pm_lock);
431 mutex_destroy(&wcd9xxx->io_lock);
432 mutex_destroy(&wcd9xxx->xfer_lock);
433 return ret;
434}
435
436static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
437{
438 wcd9xxx_irq_exit(wcd9xxx);
439 wcd9xxx_bring_down(wcd9xxx);
440 wcd9xxx_free_reset(wcd9xxx);
441 mutex_destroy(&wcd9xxx->pm_lock);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700442 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530443 mutex_destroy(&wcd9xxx->io_lock);
444 mutex_destroy(&wcd9xxx->xfer_lock);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700445 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
446 slim_remove_device(wcd9xxx->slim_slave);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530447 kfree(wcd9xxx);
448}
449
450
451#ifdef CONFIG_DEBUG_FS
452struct wcd9xxx *debugCodec;
453
454static struct dentry *debugfs_wcd9xxx_dent;
455static struct dentry *debugfs_peek;
456static struct dentry *debugfs_poke;
457
458static unsigned char read_data;
459
460static int codec_debug_open(struct inode *inode, struct file *file)
461{
462 file->private_data = inode->i_private;
463 return 0;
464}
465
466static int get_parameters(char *buf, long int *param1, int num_of_par)
467{
468 char *token;
469 int base, cnt;
470
471 token = strsep(&buf, " ");
472
473 for (cnt = 0; cnt < num_of_par; cnt++) {
474 if (token != NULL) {
475 if ((token[1] == 'x') || (token[1] == 'X'))
476 base = 16;
477 else
478 base = 10;
479
480 if (strict_strtoul(token, base, &param1[cnt]) != 0)
481 return -EINVAL;
482
483 token = strsep(&buf, " ");
484 } else
485 return -EINVAL;
486 }
487 return 0;
488}
489
490static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
491 size_t count, loff_t *ppos)
492{
493 char lbuf[8];
494
495 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
496 return simple_read_from_buffer(ubuf, count, ppos, lbuf,
497 strnlen(lbuf, 7));
498}
499
500
501static ssize_t codec_debug_write(struct file *filp,
502 const char __user *ubuf, size_t cnt, loff_t *ppos)
503{
504 char *access_str = filp->private_data;
505 char lbuf[32];
506 int rc;
507 long int param[5];
508
509 if (cnt > sizeof(lbuf) - 1)
510 return -EINVAL;
511
512 rc = copy_from_user(lbuf, ubuf, cnt);
513 if (rc)
514 return -EFAULT;
515
516 lbuf[cnt] = '\0';
517
518 if (!strncmp(access_str, "poke", 6)) {
519 /* write */
520 rc = get_parameters(lbuf, param, 2);
521 if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
522 (rc == 0))
523 wcd9xxx_interface_reg_write(debugCodec, param[0],
524 param[1]);
525 else
526 rc = -EINVAL;
527 } else if (!strncmp(access_str, "peek", 6)) {
528 /* read */
529 rc = get_parameters(lbuf, param, 1);
530 if ((param[0] <= 0x3FF) && (rc == 0))
531 read_data = wcd9xxx_interface_reg_read(debugCodec,
532 param[0]);
533 else
534 rc = -EINVAL;
535 }
536
537 if (rc == 0)
538 rc = cnt;
539 else
540 pr_err("%s: rc = %d\n", __func__, rc);
541
542 return rc;
543}
544
545static const struct file_operations codec_debug_ops = {
546 .open = codec_debug_open,
547 .write = codec_debug_write,
548 .read = codec_debug_read
549};
550#endif
551
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700552static int wcd9xxx_enable_supplies(struct wcd9xxx *wcd9xxx,
553 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530554{
555 int ret;
556 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530557 wcd9xxx->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
558 ARRAY_SIZE(pdata->regulator),
559 GFP_KERNEL);
560 if (!wcd9xxx->supplies) {
561 ret = -ENOMEM;
562 goto err;
563 }
564
Kiran Kandi725f8492012-08-06 13:45:16 -0700565 wcd9xxx->num_of_supplies = 0;
Simmi Pateriya4fd69932012-10-26 00:57:06 +0530566
567 if (ARRAY_SIZE(pdata->regulator) > MAX_REGULATOR) {
568 pr_err("%s: Array Size out of bound\n", __func__);
569 ret = -EINVAL;
570 goto err;
571 }
572
Kiran Kandi725f8492012-08-06 13:45:16 -0700573 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
574 if (pdata->regulator[i].name) {
575 wcd9xxx->supplies[i].supply = pdata->regulator[i].name;
576 wcd9xxx->num_of_supplies++;
577 }
578 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530579
Kiran Kandi725f8492012-08-06 13:45:16 -0700580 ret = regulator_bulk_get(wcd9xxx->dev, wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530581 wcd9xxx->supplies);
582 if (ret != 0) {
583 dev_err(wcd9xxx->dev, "Failed to get supplies: err = %d\n",
584 ret);
585 goto err_supplies;
586 }
587
Kiran Kandi725f8492012-08-06 13:45:16 -0700588 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530589 ret = regulator_set_voltage(wcd9xxx->supplies[i].consumer,
590 pdata->regulator[i].min_uV, pdata->regulator[i].max_uV);
591 if (ret) {
592 pr_err("%s: Setting regulator voltage failed for "
593 "regulator %s err = %d\n", __func__,
594 wcd9xxx->supplies[i].supply, ret);
595 goto err_get;
596 }
597
598 ret = regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer,
599 pdata->regulator[i].optimum_uA);
600 if (ret < 0) {
601 pr_err("%s: Setting regulator optimum mode failed for "
602 "regulator %s err = %d\n", __func__,
603 wcd9xxx->supplies[i].supply, ret);
604 goto err_get;
605 }
606 }
607
Kiran Kandi725f8492012-08-06 13:45:16 -0700608 ret = regulator_bulk_enable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530609 wcd9xxx->supplies);
610 if (ret != 0) {
611 dev_err(wcd9xxx->dev, "Failed to enable supplies: err = %d\n",
612 ret);
613 goto err_configure;
614 }
615 return ret;
616
617err_configure:
Kiran Kandi725f8492012-08-06 13:45:16 -0700618 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530619 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
620 pdata->regulator[i].max_uV);
621 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
622 }
623err_get:
Kiran Kandi725f8492012-08-06 13:45:16 -0700624 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530625err_supplies:
626 kfree(wcd9xxx->supplies);
627err:
628 return ret;
629}
630
Venkat Sudhir49203862012-05-21 14:29:13 -0700631static void wcd9xxx_disable_supplies(struct wcd9xxx *wcd9xxx,
632 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530633{
634 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530635
Kiran Kandi725f8492012-08-06 13:45:16 -0700636 regulator_bulk_disable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530637 wcd9xxx->supplies);
Kiran Kandi725f8492012-08-06 13:45:16 -0700638 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530639 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
640 pdata->regulator[i].max_uV);
641 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
642 }
Kiran Kandi725f8492012-08-06 13:45:16 -0700643 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530644 kfree(wcd9xxx->supplies);
645}
646
647int wcd9xxx_get_intf_type(void)
648{
649 return wcd9xxx_intf;
650}
651EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
652
653struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
654{
655 u16 mask = 0x0f00;
656 int value = 0;
657 struct wcd9xxx_i2c *wcd9xxx = NULL;
658 value = ((reg & mask) >> 8) & 0x000f;
659 switch (value) {
660 case 0:
661 wcd9xxx = &wcd9xxx_modules[0];
662 break;
663 case 1:
664 wcd9xxx = &wcd9xxx_modules[1];
665 break;
666 case 2:
667 wcd9xxx = &wcd9xxx_modules[2];
668 break;
669 case 3:
670 wcd9xxx = &wcd9xxx_modules[3];
671 break;
672 default:
673 break;
674 }
675 return wcd9xxx;
676}
677
678int wcd9xxx_i2c_write_device(u16 reg, u8 *value,
679 u32 bytes)
680{
681
682 struct i2c_msg *msg;
683 int ret = 0;
684 u8 reg_addr = 0;
685 u8 data[bytes + 1];
686 struct wcd9xxx_i2c *wcd9xxx;
687
688 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
689 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
690 pr_err("failed to get device info\n");
691 return -ENODEV;
692 }
693 reg_addr = (u8)reg;
694 msg = &wcd9xxx->xfer_msg[0];
695 msg->addr = wcd9xxx->client->addr;
696 msg->len = bytes + 1;
697 msg->flags = 0;
698 data[0] = reg;
699 data[1] = *value;
700 msg->buf = data;
701 ret = i2c_transfer(wcd9xxx->client->adapter, wcd9xxx->xfer_msg, 1);
702 /* Try again if the write fails */
703 if (ret != 1) {
704 ret = i2c_transfer(wcd9xxx->client->adapter,
705 wcd9xxx->xfer_msg, 1);
706 if (ret != 1) {
707 pr_err("failed to write the device\n");
708 return ret;
709 }
710 }
711 pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
712 return 0;
713}
714
715
716int wcd9xxx_i2c_read_device(unsigned short reg,
717 int bytes, unsigned char *dest)
718{
719 struct i2c_msg *msg;
720 int ret = 0;
721 u8 reg_addr = 0;
722 struct wcd9xxx_i2c *wcd9xxx;
723 u8 i = 0;
724
725 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
726 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
727 pr_err("failed to get device info\n");
728 return -ENODEV;
729 }
730 for (i = 0; i < bytes; i++) {
731 reg_addr = (u8)reg++;
732 msg = &wcd9xxx->xfer_msg[0];
733 msg->addr = wcd9xxx->client->addr;
734 msg->len = 1;
735 msg->flags = 0;
736 msg->buf = &reg_addr;
737
738 msg = &wcd9xxx->xfer_msg[1];
739 msg->addr = wcd9xxx->client->addr;
740 msg->len = 1;
741 msg->flags = I2C_M_RD;
742 msg->buf = dest++;
743 ret = i2c_transfer(wcd9xxx->client->adapter,
744 wcd9xxx->xfer_msg, 2);
745
746 /* Try again if read fails first time */
747 if (ret != 2) {
748 ret = i2c_transfer(wcd9xxx->client->adapter,
749 wcd9xxx->xfer_msg, 2);
750 if (ret != 2) {
751 pr_err("failed to read wcd9xxx register\n");
752 return ret;
753 }
754 }
755 }
756 return 0;
757}
758
759int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
760 int bytes, void *dest, bool interface_reg)
761{
762 return wcd9xxx_i2c_read_device(reg, bytes, dest);
763}
764
765int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
766 int bytes, void *src, bool interface_reg)
767{
768 return wcd9xxx_i2c_write_device(reg, src, bytes);
769}
770
771static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
772 const struct i2c_device_id *id)
773{
774 struct wcd9xxx *wcd9xxx;
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700775 struct wcd9xxx_pdata *pdata;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530776 int val = 0;
777 int ret = 0;
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530778 int i2c_mode = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530779 static int device_id;
Venkat Sudhira41630a2012-10-27 00:57:31 -0700780 struct device *dev;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530781
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530782 pr_info("%s\n", __func__);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700783 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
Venkat Sudhira41630a2012-10-27 00:57:31 -0700784 dev_dbg(&client->dev, "%s:Codec is detected in slimbus mode\n",
785 __func__);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700786 return -ENODEV;
787 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530788 if (device_id > 0) {
789 wcd9xxx_modules[device_id++].client = client;
Venkat Sudhira41630a2012-10-27 00:57:31 -0700790 dev_dbg(&client->dev, "%s:probe for other slaves\n"
791 "devices of codec\n", __func__);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530792 return ret;
793 }
Venkat Sudhira41630a2012-10-27 00:57:31 -0700794 dev = &client->dev;
795 if (client->dev.of_node) {
796 dev_dbg(&client->dev, "%s:Platform data from device tree\n",
797 __func__);
798 pdata = wcd9xxx_populate_dt_pdata(&client->dev);
799 client->dev.platform_data = pdata;
800 } else {
801 dev_dbg(&client->dev, "%s:Platform data from board file\n",
802 __func__);
803 pdata = client->dev.platform_data;
804 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530805 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
806 if (wcd9xxx == NULL) {
807 pr_err("%s: error, allocation failed\n", __func__);
808 ret = -ENOMEM;
809 goto fail;
810 }
811
812 if (!pdata) {
813 dev_dbg(&client->dev, "no platform data?\n");
814 ret = -EINVAL;
815 goto fail;
816 }
817 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
818 dev_dbg(&client->dev, "can't talk I2C?\n");
819 ret = -EIO;
820 goto fail;
821 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530822 dev_set_drvdata(&client->dev, wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530823 wcd9xxx->dev = &client->dev;
824 wcd9xxx->reset_gpio = pdata->reset_gpio;
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700825 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530826 if (ret) {
827 pr_err("%s: Fail to enable Codec supplies\n", __func__);
828 goto err_codec;
829 }
830
831 usleep_range(5, 5);
832 ret = wcd9xxx_reset(wcd9xxx);
833 if (ret) {
834 pr_err("%s: Resetting Codec failed\n", __func__);
835 goto err_supplies;
836 }
837 wcd9xxx_modules[device_id++].client = client;
838
839 wcd9xxx->read_dev = wcd9xxx_i2c_read;
840 wcd9xxx->write_dev = wcd9xxx_i2c_write;
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700841 if (!wcd9xxx->dev->of_node) {
842 wcd9xxx->irq = pdata->irq;
843 wcd9xxx->irq_base = pdata->irq_base;
844 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530845
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700846 ret = wcd9xxx_device_init(wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530847 if (ret) {
848 pr_err("%s: error, initializing device failed\n", __func__);
849 goto err_device_init;
850 }
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530851
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700852 if ((wcd9xxx->idbyte[0] == 0x2) || (wcd9xxx->idbyte[0] == 0x1))
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530853 i2c_mode = TABLA_I2C_MODE;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700854 else if (wcd9xxx->idbyte[0] == 0x0)
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530855 i2c_mode = SITAR_I2C_MODE;
856
857 ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
858
859 if ((ret < 0) || (val != i2c_mode))
860 pr_err("failed to read the wcd9xxx status ret = %d\n", ret);
861
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530862 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
863
864 return ret;
865err_device_init:
866 wcd9xxx_free_reset(wcd9xxx);
867err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -0700868 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530869err_codec:
870 kfree(wcd9xxx);
871fail:
872 return ret;
873}
874
875static int __devexit wcd9xxx_i2c_remove(struct i2c_client *client)
876{
877 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -0700878 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530879 pr_debug("exit\n");
880 wcd9xxx = dev_get_drvdata(&client->dev);
Venkat Sudhir49203862012-05-21 14:29:13 -0700881 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530882 wcd9xxx_device_exit(wcd9xxx);
883 return 0;
884}
885
Kiran Kandi725f8492012-08-06 13:45:16 -0700886static int wcd9xxx_dt_parse_vreg_info(struct device *dev,
887 struct wcd9xxx_regulator *vreg, const char *vreg_name)
888{
889 int len, ret = 0;
890 const __be32 *prop;
891 char prop_name[CODEC_DT_MAX_PROP_SIZE];
892 struct device_node *regnode = NULL;
893 u32 prop_val;
894
895 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
896 vreg_name);
897 regnode = of_parse_phandle(dev->of_node, prop_name, 0);
898
899 if (!regnode) {
900 dev_err(dev, "Looking up %s property in node %s failed",
901 prop_name, dev->of_node->full_name);
902 return -ENODEV;
903 }
904 vreg->name = vreg_name;
905
906 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
907 "qcom,%s-voltage", vreg_name);
908 prop = of_get_property(dev->of_node, prop_name, &len);
909
910 if (!prop || (len != (2 * sizeof(__be32)))) {
911 dev_err(dev, "%s %s property\n",
912 prop ? "invalid format" : "no", prop_name);
913 return -ENODEV;
914 } else {
915 vreg->min_uV = be32_to_cpup(&prop[0]);
916 vreg->max_uV = be32_to_cpup(&prop[1]);
917 }
918
919 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
920 "qcom,%s-current", vreg_name);
921
922 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
923 if (ret) {
924 dev_err(dev, "Looking up %s property in node %s failed",
925 prop_name, dev->of_node->full_name);
926 return -ENODEV;
927 }
928 vreg->optimum_uA = prop_val;
929
930 dev_info(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
931 vreg->min_uV, vreg->max_uV, vreg->optimum_uA);
932 return 0;
933}
934
935static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
936 struct wcd9xxx_micbias_setting *micbias)
937{
938 int ret = 0;
939 char prop_name[CODEC_DT_MAX_PROP_SIZE];
940 u32 prop_val;
941
942 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
943 "qcom,cdc-micbias-ldoh-v");
944 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
945 if (ret) {
946 dev_err(dev, "Looking up %s property in node %s failed",
947 prop_name, dev->of_node->full_name);
948 return -ENODEV;
949 }
950 micbias->ldoh_v = (u8)prop_val;
951
952 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
953 "qcom,cdc-micbias-cfilt1-mv");
954 ret = of_property_read_u32(dev->of_node, prop_name,
955 &micbias->cfilt1_mv);
956 if (ret) {
957 dev_err(dev, "Looking up %s property in node %s failed",
958 prop_name, dev->of_node->full_name);
959 return -ENODEV;
960 }
961
962 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
963 "qcom,cdc-micbias-cfilt2-mv");
964 ret = of_property_read_u32(dev->of_node, prop_name,
965 &micbias->cfilt2_mv);
966 if (ret) {
967 dev_err(dev, "Looking up %s property in node %s failed",
968 prop_name, dev->of_node->full_name);
969 return -ENODEV;
970 }
971
972 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
973 "qcom,cdc-micbias-cfilt3-mv");
974 ret = of_property_read_u32(dev->of_node, prop_name,
975 &micbias->cfilt3_mv);
976 if (ret) {
977 dev_err(dev, "Looking up %s property in node %s failed",
978 prop_name, dev->of_node->full_name);
979 return -ENODEV;
980 }
981
982 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
983 "qcom,cdc-micbias1-cfilt-sel");
984 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
985 if (ret) {
986 dev_err(dev, "Looking up %s property in node %s failed",
987 prop_name, dev->of_node->full_name);
988 return -ENODEV;
989 }
990 micbias->bias1_cfilt_sel = (u8)prop_val;
991
992 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
993 "qcom,cdc-micbias2-cfilt-sel");
994 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
995 if (ret) {
996 dev_err(dev, "Looking up %s property in node %s failed",
997 prop_name, dev->of_node->full_name);
998 return -ENODEV;
999 }
1000 micbias->bias2_cfilt_sel = (u8)prop_val;
1001
1002 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
1003 "qcom,cdc-micbias3-cfilt-sel");
1004 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
1005 if (ret) {
1006 dev_err(dev, "Looking up %s property in node %s failed",
1007 prop_name, dev->of_node->full_name);
1008 return -ENODEV;
1009 }
1010 micbias->bias3_cfilt_sel = (u8)prop_val;
1011
1012 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
1013 "qcom,cdc-micbias4-cfilt-sel");
1014 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
1015 if (ret) {
1016 dev_err(dev, "Looking up %s property in node %s failed",
1017 prop_name, dev->of_node->full_name);
1018 return -ENODEV;
1019 }
1020 micbias->bias4_cfilt_sel = (u8)prop_val;
1021
Joonwoo Parkadf25972012-10-18 13:18:08 -07001022 /* micbias external cap */
1023 micbias->bias1_cap_mode =
1024 (of_property_read_bool(dev->of_node, "qcom,cdc-micbias1-ext-cap") ?
1025 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
1026 micbias->bias2_cap_mode =
1027 (of_property_read_bool(dev->of_node, "qcom,cdc-micbias2-ext-cap") ?
1028 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
1029 micbias->bias3_cap_mode =
1030 (of_property_read_bool(dev->of_node, "qcom,cdc-micbias3-ext-cap") ?
1031 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
1032 micbias->bias4_cap_mode =
1033 (of_property_read_bool(dev->of_node, "qcom,cdc-micbias4-ext-cap") ?
1034 MICBIAS_EXT_BYP_CAP : MICBIAS_NO_EXT_BYP_CAP);
1035
Kiran Kandi725f8492012-08-06 13:45:16 -07001036 dev_dbg(dev, "ldoh_v %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u",
1037 (u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv,
1038 (u32)micbias->cfilt2_mv, (u32)micbias->cfilt3_mv);
1039
1040 dev_dbg(dev, "bias1_cfilt_sel %u bias2_cfilt_sel %u\n",
1041 (u32)micbias->bias1_cfilt_sel, (u32)micbias->bias2_cfilt_sel);
1042
1043 dev_dbg(dev, "bias3_cfilt_sel %u bias4_cfilt_sel %u\n",
1044 (u32)micbias->bias3_cfilt_sel, (u32)micbias->bias4_cfilt_sel);
1045
Joonwoo Parkadf25972012-10-18 13:18:08 -07001046 dev_dbg(dev, "bias1_ext_cap %d bias2_ext_cap %d\n",
1047 micbias->bias1_cap_mode, micbias->bias2_cap_mode);
1048 dev_dbg(dev, "bias3_ext_cap %d bias4_ext_cap %d\n",
1049 micbias->bias3_cap_mode, micbias->bias4_cap_mode);
1050
Kiran Kandi725f8492012-08-06 13:45:16 -07001051 return 0;
1052}
1053
1054static int wcd9xxx_dt_parse_slim_interface_dev_info(struct device *dev,
1055 struct slim_device *slim_ifd)
1056{
1057 int ret = 0;
1058 struct property *prop;
1059
1060 ret = of_property_read_string(dev->of_node, "qcom,cdc-slim-ifd",
1061 &slim_ifd->name);
1062 if (ret) {
1063 dev_err(dev, "Looking up %s property in node %s failed",
1064 "qcom,cdc-slim-ifd-dev", dev->of_node->full_name);
1065 return -ENODEV;
1066 }
1067 prop = of_find_property(dev->of_node,
1068 "qcom,cdc-slim-ifd-elemental-addr", NULL);
1069 if (!prop) {
1070 dev_err(dev, "Looking up %s property in node %s failed",
1071 "qcom,cdc-slim-ifd-elemental-addr",
1072 dev->of_node->full_name);
1073 return -ENODEV;
1074 } else if (prop->length != 6) {
1075 dev_err(dev, "invalid codec slim ifd addr. addr length = %d\n",
1076 prop->length);
1077 return -ENODEV;
1078 }
1079 memcpy(slim_ifd->e_addr, prop->value, 6);
1080
1081 return 0;
1082}
1083
Kiran Kandi725f8492012-08-06 13:45:16 -07001084static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev)
1085{
1086 struct wcd9xxx_pdata *pdata;
1087 int ret, i;
1088 char **codec_supplies;
1089 u32 num_of_supplies = 0;
1090
1091 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1092 if (!pdata) {
Venkat Sudhira41630a2012-10-27 00:57:31 -07001093 dev_err(dev, "could not allocate memory for platform data\n");
Kiran Kandi725f8492012-08-06 13:45:16 -07001094 return NULL;
1095 }
Venkat Sudhira41630a2012-10-27 00:57:31 -07001096 if (!strcmp(dev_name(dev), "taiko-slim-pgd") ||
1097 (!strcmp(dev_name(dev), WCD9XXX_I2C_GSBI_SLAVE_ID))) {
Kiran Kandi725f8492012-08-06 13:45:16 -07001098 codec_supplies = taiko_supplies;
1099 num_of_supplies = ARRAY_SIZE(taiko_supplies);
1100 } else {
1101 dev_err(dev, "%s unsupported device %s\n",
1102 __func__, dev_name(dev));
1103 goto err;
1104 }
1105
1106 if (num_of_supplies > ARRAY_SIZE(pdata->regulator)) {
1107 dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
1108 __func__, num_of_supplies, ARRAY_SIZE(pdata->regulator));
1109
1110 goto err;
1111 }
1112
1113 for (i = 0; i < num_of_supplies; i++) {
1114 ret = wcd9xxx_dt_parse_vreg_info(dev, &pdata->regulator[i],
1115 codec_supplies[i]);
1116 if (ret)
1117 goto err;
1118 }
1119
1120 ret = wcd9xxx_dt_parse_micbias_info(dev, &pdata->micbias);
1121 if (ret)
1122 goto err;
1123
1124 pdata->reset_gpio = of_get_named_gpio(dev->of_node,
1125 "qcom,cdc-reset-gpio", 0);
1126 if (pdata->reset_gpio < 0) {
1127 dev_err(dev, "Looking up %s property in node %s failed %d\n",
1128 "qcom, cdc-reset-gpio", dev->of_node->full_name,
1129 pdata->reset_gpio);
1130 goto err;
1131 }
Venkat Sudhira41630a2012-10-27 00:57:31 -07001132 dev_dbg(dev, "%s: reset gpio %d", __func__, pdata->reset_gpio);
Kiran Kandi725f8492012-08-06 13:45:16 -07001133 return pdata;
1134err:
1135 devm_kfree(dev, pdata);
1136 return NULL;
1137}
1138
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001139static int wcd9xxx_slim_get_laddr(struct slim_device *sb,
1140 const u8 *e_addr, u8 e_len, u8 *laddr)
1141{
1142 int ret;
1143 const unsigned long timeout = jiffies +
1144 msecs_to_jiffies(SLIMBUS_PRESENT_TIMEOUT);
1145
1146 do {
1147 ret = slim_get_logical_addr(sb, e_addr, e_len, laddr);
1148 if (!ret)
1149 break;
1150 /* Give SLIMBUS time to report present and be ready. */
1151 usleep_range(1000, 1000);
1152 pr_debug_ratelimited("%s: retyring get logical addr\n",
1153 __func__);
1154 } while time_before(jiffies, timeout);
1155
1156 return ret;
1157}
1158
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301159static int wcd9xxx_slim_probe(struct slim_device *slim)
1160{
1161 struct wcd9xxx *wcd9xxx;
1162 struct wcd9xxx_pdata *pdata;
1163 int ret = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301164
Kiran Kandi725f8492012-08-06 13:45:16 -07001165 if (slim->dev.of_node) {
1166 dev_info(&slim->dev, "Platform data from device tree\n");
1167 pdata = wcd9xxx_populate_dt_pdata(&slim->dev);
Venkat Sudhira41630a2012-10-27 00:57:31 -07001168 ret = wcd9xxx_dt_parse_slim_interface_dev_info(&slim->dev,
1169 &pdata->slimbus_slave_device);
1170 if (ret) {
1171 dev_err(&slim->dev, "Error, parsing slim interface\n");
1172 devm_kfree(&slim->dev, pdata);
1173 ret = -EINVAL;
1174 goto err;
1175 }
Kiran Kandi725f8492012-08-06 13:45:16 -07001176 slim->dev.platform_data = pdata;
1177
1178 } else {
1179 dev_info(&slim->dev, "Platform data from board file\n");
1180 pdata = slim->dev.platform_data;
1181 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301182
1183 if (!pdata) {
1184 dev_err(&slim->dev, "Error, no platform data\n");
1185 ret = -EINVAL;
1186 goto err;
1187 }
1188
1189 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
1190 if (wcd9xxx == NULL) {
1191 pr_err("%s: error, allocation failed\n", __func__);
1192 ret = -ENOMEM;
1193 goto err;
1194 }
1195 if (!slim->ctrl) {
1196 pr_err("Error, no SLIMBUS control data\n");
1197 ret = -EINVAL;
1198 goto err_codec;
1199 }
1200 wcd9xxx->slim = slim;
1201 slim_set_clientdata(slim, wcd9xxx);
1202 wcd9xxx->reset_gpio = pdata->reset_gpio;
1203 wcd9xxx->dev = &slim->dev;
1204
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -07001205 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301206 if (ret)
1207 goto err_codec;
1208 usleep_range(5, 5);
1209
1210 ret = wcd9xxx_reset(wcd9xxx);
1211 if (ret) {
1212 pr_err("%s: Resetting Codec failed\n", __func__);
1213 goto err_supplies;
1214 }
1215
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001216 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
1217 ARRAY_SIZE(wcd9xxx->slim->e_addr),
1218 &wcd9xxx->slim->laddr);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301219 if (ret) {
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001220 pr_err("%s: failed to get slimbus %s logical address: %d\n",
1221 __func__, wcd9xxx->slim->name, ret);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301222 goto err_reset;
1223 }
1224 wcd9xxx->read_dev = wcd9xxx_slim_read_device;
1225 wcd9xxx->write_dev = wcd9xxx_slim_write_device;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301226 wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301227 wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
Joonwoo Parkf6574c72012-10-10 17:29:57 -07001228 if (!wcd9xxx->dev->of_node) {
1229 wcd9xxx->irq = pdata->irq;
1230 wcd9xxx->irq_base = pdata->irq_base;
1231 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301232
1233 ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
1234 if (ret) {
1235 pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
1236 goto err_reset;
1237 }
1238
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001239 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim_slave,
1240 wcd9xxx->slim_slave->e_addr,
1241 ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
1242 &wcd9xxx->slim_slave->laddr);
1243 if (ret) {
1244 pr_err("%s: failed to get slimbus %s logical address: %d\n",
1245 __func__, wcd9xxx->slim->name, ret);
1246 goto err_slim_add;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301247 }
1248 wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
1249 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_SLIMBUS;
1250
Joonwoo Parkf6574c72012-10-10 17:29:57 -07001251 ret = wcd9xxx_device_init(wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301252 if (ret) {
1253 pr_err("%s: error, initializing device failed\n", __func__);
1254 goto err_slim_add;
1255 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301256#ifdef CONFIG_DEBUG_FS
1257 debugCodec = wcd9xxx;
1258
1259 debugfs_wcd9xxx_dent = debugfs_create_dir
1260 ("wcd9310_slimbus_interface_device", 0);
1261 if (!IS_ERR(debugfs_wcd9xxx_dent)) {
1262 debugfs_peek = debugfs_create_file("peek",
1263 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1264 (void *) "peek", &codec_debug_ops);
1265
1266 debugfs_poke = debugfs_create_file("poke",
1267 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1268 (void *) "poke", &codec_debug_ops);
1269 }
1270#endif
1271
1272 return ret;
1273
1274err_slim_add:
1275 slim_remove_device(wcd9xxx->slim_slave);
1276err_reset:
1277 wcd9xxx_free_reset(wcd9xxx);
1278err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -07001279 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301280err_codec:
1281 kfree(wcd9xxx);
1282err:
1283 return ret;
1284}
1285static int wcd9xxx_slim_remove(struct slim_device *pdev)
1286{
1287 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -07001288 struct wcd9xxx_pdata *pdata = pdev->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301289
1290#ifdef CONFIG_DEBUG_FS
1291 debugfs_remove(debugfs_peek);
1292 debugfs_remove(debugfs_poke);
1293 debugfs_remove(debugfs_wcd9xxx_dent);
1294#endif
1295 wcd9xxx = slim_get_devicedata(pdev);
1296 wcd9xxx_deinit_slimslave(wcd9xxx);
1297 slim_remove_device(wcd9xxx->slim_slave);
Venkat Sudhir49203862012-05-21 14:29:13 -07001298 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301299 wcd9xxx_device_exit(wcd9xxx);
1300 return 0;
1301}
1302
1303static int wcd9xxx_resume(struct wcd9xxx *wcd9xxx)
1304{
1305 int ret = 0;
1306
1307 pr_debug("%s: enter\n", __func__);
1308 mutex_lock(&wcd9xxx->pm_lock);
1309 if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1310 pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
1311 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1312 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
1313 } else {
1314 pr_warn("%s: system is already awake, state %d wlock %d\n",
1315 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1316 }
1317 mutex_unlock(&wcd9xxx->pm_lock);
1318 wake_up_all(&wcd9xxx->pm_wq);
1319
1320 return ret;
1321}
1322
1323static int wcd9xxx_slim_resume(struct slim_device *sldev)
1324{
1325 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1326 return wcd9xxx_resume(wcd9xxx);
1327}
1328
1329static int wcd9xxx_i2c_resume(struct i2c_client *i2cdev)
1330{
1331 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301332 if (wcd9xxx)
1333 return wcd9xxx_resume(wcd9xxx);
1334 else
1335 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301336}
1337
1338static int wcd9xxx_suspend(struct wcd9xxx *wcd9xxx, pm_message_t pmesg)
1339{
1340 int ret = 0;
1341
1342 pr_debug("%s: enter\n", __func__);
Stephen Boyd2fcabf92012-05-30 10:41:11 -07001343 /*
1344 * pm_qos_update_request() can be called after this suspend chain call
1345 * started. thus suspend can be called while lock is being held
1346 */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301347 mutex_lock(&wcd9xxx->pm_lock);
1348 if (wcd9xxx->pm_state == WCD9XXX_PM_SLEEPABLE) {
1349 pr_debug("%s: suspending system, state %d, wlock %d\n",
1350 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1351 wcd9xxx->pm_state = WCD9XXX_PM_ASLEEP;
1352 } else if (wcd9xxx->pm_state == WCD9XXX_PM_AWAKE) {
1353 /* unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
1354 * then set to WCD9XXX_PM_ASLEEP */
1355 pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
1356 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1357 mutex_unlock(&wcd9xxx->pm_lock);
1358 if (!(wait_event_timeout(wcd9xxx->pm_wq,
1359 wcd9xxx_pm_cmpxchg(wcd9xxx,
1360 WCD9XXX_PM_SLEEPABLE,
1361 WCD9XXX_PM_ASLEEP) ==
1362 WCD9XXX_PM_SLEEPABLE,
1363 HZ))) {
1364 pr_debug("%s: suspend failed state %d, wlock %d\n",
1365 __func__, wcd9xxx->pm_state,
1366 wcd9xxx->wlock_holders);
1367 ret = -EBUSY;
1368 } else {
1369 pr_debug("%s: done, state %d, wlock %d\n", __func__,
1370 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1371 }
1372 mutex_lock(&wcd9xxx->pm_lock);
1373 } else if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1374 pr_warn("%s: system is already suspended, state %d, wlock %dn",
1375 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1376 }
1377 mutex_unlock(&wcd9xxx->pm_lock);
1378
1379 return ret;
1380}
1381
1382static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
1383{
1384 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1385 return wcd9xxx_suspend(wcd9xxx, pmesg);
1386}
1387
1388static int wcd9xxx_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
1389{
1390 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301391 if (wcd9xxx)
1392 return wcd9xxx_suspend(wcd9xxx, pmesg);
1393 else
1394 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301395}
1396
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301397static const struct slim_device_id sitar_slimtest_id[] = {
1398 {"sitar-slim", 0},
1399 {}
1400};
1401static struct slim_driver sitar_slim_driver = {
1402 .driver = {
1403 .name = "sitar-slim",
1404 .owner = THIS_MODULE,
1405 },
1406 .probe = wcd9xxx_slim_probe,
1407 .remove = wcd9xxx_slim_remove,
1408 .id_table = sitar_slimtest_id,
1409 .resume = wcd9xxx_slim_resume,
1410 .suspend = wcd9xxx_slim_suspend,
1411};
1412
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001413static const struct slim_device_id sitar1p1_slimtest_id[] = {
1414 {"sitar1p1-slim", 0},
1415 {}
1416};
1417static struct slim_driver sitar1p1_slim_driver = {
1418 .driver = {
1419 .name = "sitar1p1-slim",
1420 .owner = THIS_MODULE,
1421 },
1422 .probe = wcd9xxx_slim_probe,
1423 .remove = wcd9xxx_slim_remove,
1424 .id_table = sitar1p1_slimtest_id,
1425 .resume = wcd9xxx_slim_resume,
1426 .suspend = wcd9xxx_slim_suspend,
1427};
1428
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301429static const struct slim_device_id slimtest_id[] = {
1430 {"tabla-slim", 0},
1431 {}
1432};
1433
1434static struct slim_driver tabla_slim_driver = {
1435 .driver = {
1436 .name = "tabla-slim",
1437 .owner = THIS_MODULE,
1438 },
1439 .probe = wcd9xxx_slim_probe,
1440 .remove = wcd9xxx_slim_remove,
1441 .id_table = slimtest_id,
1442 .resume = wcd9xxx_slim_resume,
1443 .suspend = wcd9xxx_slim_suspend,
1444};
1445
1446static const struct slim_device_id slimtest2x_id[] = {
1447 {"tabla2x-slim", 0},
1448 {}
1449};
1450
1451static struct slim_driver tabla2x_slim_driver = {
1452 .driver = {
1453 .name = "tabla2x-slim",
1454 .owner = THIS_MODULE,
1455 },
1456 .probe = wcd9xxx_slim_probe,
1457 .remove = wcd9xxx_slim_remove,
1458 .id_table = slimtest2x_id,
1459 .resume = wcd9xxx_slim_resume,
1460 .suspend = wcd9xxx_slim_suspend,
1461};
1462
Joonwoo Parka7172112012-07-23 16:03:49 -07001463static const struct slim_device_id taiko_slimtest_id[] = {
Kiran Kandi725f8492012-08-06 13:45:16 -07001464 {"taiko-slim-pgd", 0},
Joonwoo Parka7172112012-07-23 16:03:49 -07001465 {}
1466};
1467
1468static struct slim_driver taiko_slim_driver = {
1469 .driver = {
1470 .name = "taiko-slim",
1471 .owner = THIS_MODULE,
1472 },
1473 .probe = wcd9xxx_slim_probe,
1474 .remove = wcd9xxx_slim_remove,
1475 .id_table = taiko_slimtest_id,
1476 .resume = wcd9xxx_slim_resume,
1477 .suspend = wcd9xxx_slim_suspend,
1478};
1479
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301480#define WCD9XXX_I2C_TOP_LEVEL 0
1481#define WCD9XXX_I2C_ANALOG 1
1482#define WCD9XXX_I2C_DIGITAL_1 2
1483#define WCD9XXX_I2C_DIGITAL_2 3
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301484
Venkat Sudhira41630a2012-10-27 00:57:31 -07001485static struct i2c_device_id wcd9xxx_id_table[] = {
1486 {"wcd9xxx-i2c", WCD9XXX_I2C_TOP_LEVEL},
1487 {"wcd9xxx-i2c", WCD9XXX_I2C_ANALOG},
1488 {"wcd9xxx-i2c", WCD9XXX_I2C_DIGITAL_1},
1489 {"wcd9xxx-i2c", WCD9XXX_I2C_DIGITAL_2},
1490 {}
1491};
1492
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301493static struct i2c_device_id tabla_id_table[] = {
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301494 {"tabla top level", WCD9XXX_I2C_TOP_LEVEL},
1495 {"tabla analog", WCD9XXX_I2C_ANALOG},
1496 {"tabla digital1", WCD9XXX_I2C_DIGITAL_1},
1497 {"tabla digital2", WCD9XXX_I2C_DIGITAL_2},
1498 {}
1499};
1500MODULE_DEVICE_TABLE(i2c, tabla_id_table);
1501
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301502static struct i2c_driver tabla_i2c_driver = {
1503 .driver = {
1504 .owner = THIS_MODULE,
1505 .name = "tabla-i2c-core",
1506 },
1507 .id_table = tabla_id_table,
1508 .probe = wcd9xxx_i2c_probe,
1509 .remove = __devexit_p(wcd9xxx_i2c_remove),
1510 .resume = wcd9xxx_i2c_resume,
1511 .suspend = wcd9xxx_i2c_suspend,
1512};
1513
Venkat Sudhira41630a2012-10-27 00:57:31 -07001514static struct i2c_driver wcd9xxx_i2c_driver = {
1515 .driver = {
1516 .owner = THIS_MODULE,
1517 .name = "wcd9xxx-i2c-core",
1518 },
1519 .id_table = wcd9xxx_id_table,
1520 .probe = wcd9xxx_i2c_probe,
1521 .remove = __devexit_p(wcd9xxx_i2c_remove),
1522 .resume = wcd9xxx_i2c_resume,
1523 .suspend = wcd9xxx_i2c_suspend,
1524};
1525
1526
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301527static int __init wcd9xxx_init(void)
1528{
Venkat Sudhira41630a2012-10-27 00:57:31 -07001529 int ret1, ret2, ret3, ret4, ret5, ret6, ret7;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301530
1531 ret1 = slim_driver_register(&tabla_slim_driver);
1532 if (ret1 != 0)
1533 pr_err("Failed to register tabla SB driver: %d\n", ret1);
1534
1535 ret2 = slim_driver_register(&tabla2x_slim_driver);
1536 if (ret2 != 0)
1537 pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
1538
1539 ret3 = i2c_add_driver(&tabla_i2c_driver);
1540 if (ret3 != 0)
Venkat Sudhira41630a2012-10-27 00:57:31 -07001541 pr_err("failed to add the tabla2x I2C driver\n");
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301542
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301543 ret4 = slim_driver_register(&sitar_slim_driver);
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001544 if (ret4 != 0)
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301545 pr_err("Failed to register sitar SB driver: %d\n", ret4);
1546
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001547 ret5 = slim_driver_register(&sitar1p1_slim_driver);
1548 if (ret5 != 0)
1549 pr_err("Failed to register sitar SB driver: %d\n", ret5);
1550
Joonwoo Parka7172112012-07-23 16:03:49 -07001551 ret6 = slim_driver_register(&taiko_slim_driver);
1552 if (ret6 != 0)
1553 pr_err("Failed to register taiko SB driver: %d\n", ret6);
1554
Venkat Sudhira41630a2012-10-27 00:57:31 -07001555 ret7 = i2c_add_driver(&wcd9xxx_i2c_driver);
1556 if (ret7 != 0)
1557 pr_err("failed to add the wcd9xxx I2C driver\n");
1558
1559 return (ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7) ? -1 : 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301560}
1561module_init(wcd9xxx_init);
1562
1563static void __exit wcd9xxx_exit(void)
1564{
1565}
1566module_exit(wcd9xxx_exit);
1567
1568MODULE_DESCRIPTION("Codec core driver");
1569MODULE_VERSION("1.0");
1570MODULE_LICENSE("GPL v2");