blob: 0ea843c3253aaf8ccf20eb91b12da4ff2ba52a18 [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>
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053016#include <linux/slab.h>
17#include <linux/mfd/core.h>
18#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
19#include <linux/mfd/wcd9xxx/core.h>
20#include <linux/mfd/wcd9xxx/pdata.h>
21#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
22
23#include <linux/delay.h>
24#include <linux/gpio.h>
25#include <linux/debugfs.h>
26#include <linux/regulator/consumer.h>
27#include <linux/i2c.h>
28#include <sound/soc.h>
29
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053030#define WCD9XXX_REGISTER_START_OFFSET 0x800
31#define WCD9XXX_SLIM_RW_MAX_TRIES 3
Joonwoo Park3c5b2df2012-08-28 15:36:55 -070032#define SLIMBUS_PRESENT_TIMEOUT 100
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053033
34#define MAX_WCD9XXX_DEVICE 4
Asish Bhattacharya2b709d42011-11-15 10:39:23 +053035#define TABLA_I2C_MODE 0x03
36#define SITAR_I2C_MODE 0x01
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053037
38struct wcd9xxx_i2c {
39 struct i2c_client *client;
40 struct i2c_msg xfer_msg[2];
41 struct mutex xfer_lock;
42 int mod_id;
43};
44
45struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -070046static int wcd9xxx_intf = -1;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053047
48static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
49 int bytes, void *dest, bool interface_reg)
50{
51 int ret;
52 u8 *buf = dest;
53
54 if (bytes <= 0) {
55 dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
56 return -EINVAL;
57 }
58
59 ret = wcd9xxx->read_dev(wcd9xxx, reg, bytes, dest, interface_reg);
60 if (ret < 0) {
61 dev_err(wcd9xxx->dev, "Codec read failed\n");
62 return ret;
63 } else
Kiran Kandi1e6371d2012-03-29 11:48:57 -070064 dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
65 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053066
67 return 0;
68}
69int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
70{
71 u8 val;
72 int ret;
73
74 mutex_lock(&wcd9xxx->io_lock);
75 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false);
76 mutex_unlock(&wcd9xxx->io_lock);
77
78 if (ret < 0)
79 return ret;
80 else
81 return val;
82}
83EXPORT_SYMBOL_GPL(wcd9xxx_reg_read);
84
85static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
86 int bytes, void *src, bool interface_reg)
87{
88 u8 *buf = src;
89
90 if (bytes <= 0) {
91 pr_err("%s: Error, invalid write length\n", __func__);
92 return -EINVAL;
93 }
94
Kiran Kandi1e6371d2012-03-29 11:48:57 -070095 dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n",
96 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053097
98 return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
99}
100
101int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
102 u8 val)
103{
104 int ret;
105
106 mutex_lock(&wcd9xxx->io_lock);
107 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, false);
108 mutex_unlock(&wcd9xxx->io_lock);
109
110 return ret;
111}
112EXPORT_SYMBOL_GPL(wcd9xxx_reg_write);
113
114static u8 wcd9xxx_pgd_la;
115static u8 wcd9xxx_inf_la;
116
117int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
118{
119 u8 val;
120 int ret;
121
122 mutex_lock(&wcd9xxx->io_lock);
123 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, true);
124 mutex_unlock(&wcd9xxx->io_lock);
125
126 if (ret < 0)
127 return ret;
128 else
129 return val;
130}
131EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_read);
132
133int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
134 u8 val)
135{
136 int ret;
137
138 mutex_lock(&wcd9xxx->io_lock);
139 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, true);
140 mutex_unlock(&wcd9xxx->io_lock);
141
142 return ret;
143}
144EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_write);
145
146int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
147 int count, u8 *buf)
148{
149 int ret;
150
151 mutex_lock(&wcd9xxx->io_lock);
152
153 ret = wcd9xxx_read(wcd9xxx, reg, count, buf, false);
154
155 mutex_unlock(&wcd9xxx->io_lock);
156
157 return ret;
158}
159EXPORT_SYMBOL_GPL(wcd9xxx_bulk_read);
160
161int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
162 int count, u8 *buf)
163{
164 int ret;
165
166 mutex_lock(&wcd9xxx->io_lock);
167
168 ret = wcd9xxx_write(wcd9xxx, reg, count, buf, false);
169
170 mutex_unlock(&wcd9xxx->io_lock);
171
172 return ret;
173}
174EXPORT_SYMBOL_GPL(wcd9xxx_bulk_write);
175
176static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
177 int bytes, void *dest, bool interface)
178{
179 int ret;
180 struct slim_ele_access msg;
181 int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
182 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
183 msg.num_bytes = bytes;
184 msg.comp = NULL;
185
186 while (1) {
187 mutex_lock(&wcd9xxx->xfer_lock);
188 ret = slim_request_val_element(interface ?
189 wcd9xxx->slim_slave : wcd9xxx->slim,
190 &msg, dest, bytes);
191 mutex_unlock(&wcd9xxx->xfer_lock);
192 if (likely(ret == 0) || (--slim_read_tries == 0))
193 break;
194 usleep_range(5000, 5000);
195 }
196
197 if (ret)
198 pr_err("%s: Error, Codec read failed (%d)\n", __func__, ret);
199
200 return ret;
201}
202/* Interface specifies whether the write is to the interface or general
203 * registers.
204 */
205static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
206 unsigned short reg, int bytes, void *src, bool interface)
207{
208 int ret;
209 struct slim_ele_access msg;
210 int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
211 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
212 msg.num_bytes = bytes;
213 msg.comp = NULL;
214
215 while (1) {
216 mutex_lock(&wcd9xxx->xfer_lock);
217 ret = slim_change_val_element(interface ?
218 wcd9xxx->slim_slave : wcd9xxx->slim,
219 &msg, src, bytes);
220 mutex_unlock(&wcd9xxx->xfer_lock);
221 if (likely(ret == 0) || (--slim_write_tries == 0))
222 break;
223 usleep_range(5000, 5000);
224 }
225
226 if (ret)
227 pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
228
229 return ret;
230}
231
232static struct mfd_cell tabla1x_devs[] = {
233 {
234 .name = "tabla1x_codec",
235 },
236};
237
238static struct mfd_cell tabla_devs[] = {
239 {
240 .name = "tabla_codec",
241 },
242};
243
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530244static struct mfd_cell sitar_devs[] = {
245 {
246 .name = "sitar_codec",
247 },
248};
249
Joonwoo Parka7172112012-07-23 16:03:49 -0700250static struct mfd_cell taiko_devs[] = {
251 {
252 .name = "taiko_codec",
253 },
254};
255
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700256static struct wcd9xx_codec_type {
257 u8 byte[4];
258 struct mfd_cell *dev;
259 int size;
260} wcd9xxx_codecs[] = {
261 {{0x2, 0x0, 0x0, 0x1}, tabla_devs, ARRAY_SIZE(tabla_devs)},
262 {{0x1, 0x0, 0x0, 0x1}, tabla1x_devs, ARRAY_SIZE(tabla1x_devs)},
263 {{0x0, 0x0, 0x2, 0x1}, taiko_devs, ARRAY_SIZE(taiko_devs)},
264 {{0x0, 0x0, 0x0, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs)},
265 {{0x1, 0x0, 0x1, 0x1}, sitar_devs, ARRAY_SIZE(sitar_devs)},
266};
267
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530268static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
269{
270 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
271 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 0);
272 usleep_range(5000, 5000);
273 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3);
274 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3);
275}
276
277static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx)
278{
279 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x7);
280 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x6);
281 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0xe);
282 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x8);
283}
284
285static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
286{
287 int ret;
288
289 if (wcd9xxx->reset_gpio) {
290 ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
291 if (ret) {
292 pr_err("%s: Failed to request gpio %d\n", __func__,
293 wcd9xxx->reset_gpio);
294 wcd9xxx->reset_gpio = 0;
295 return ret;
296 }
297
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530298 gpio_direction_output(wcd9xxx->reset_gpio, 0);
299 msleep(20);
300 gpio_direction_output(wcd9xxx->reset_gpio, 1);
301 msleep(20);
302 }
303 return 0;
304}
305
306static void wcd9xxx_free_reset(struct wcd9xxx *wcd9xxx)
307{
308 if (wcd9xxx->reset_gpio) {
309 gpio_free(wcd9xxx->reset_gpio);
310 wcd9xxx->reset_gpio = 0;
311 }
312}
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700313static int wcd9xxx_check_codec_type(struct wcd9xxx *wcd9xxx,
314 struct mfd_cell **wcd9xxx_dev,
315 int *wcd9xxx_dev_size)
316{
317 struct wcd9xx_codec_type *cdc = wcd9xxx_codecs;
318 int index;
319 int ret;
320 index = WCD9XXX_A_CHIP_ID_BYTE_0;
321 while (index <= WCD9XXX_A_CHIP_ID_BYTE_3) {
322 ret = wcd9xxx_reg_read(wcd9xxx, index);
323 if (ret < 0)
324 goto exit;
325 wcd9xxx->idbyte[index-WCD9XXX_A_CHIP_ID_BYTE_0] = (u8)ret;
326 pr_debug("%s: wcd9xx read = %x, byte = %x\n", __func__, ret,
327 index);
328 index++;
329 }
330
331 /* Read codec version */
332 ret = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_VERSION);
333 if (ret < 0)
334 goto exit;
335 wcd9xxx->version = (u8)ret & 0x1F;
336
337 while (cdc < (cdc + ARRAY_SIZE(wcd9xxx_codecs)) && cdc != NULL) {
338 if ((cdc->byte[0] == wcd9xxx->idbyte[0]) &&
339 (cdc->byte[1] == wcd9xxx->idbyte[1]) &&
340 (cdc->byte[2] == wcd9xxx->idbyte[2]) &&
341 (cdc->byte[3] == wcd9xxx->idbyte[3])) {
342 pr_info("%s: codec is %s", __func__, cdc->dev->name);
343 *wcd9xxx_dev = cdc->dev;
344 *wcd9xxx_dev_size = cdc->size;
345 break;
346 }
347 cdc++;
348 }
349 if (*wcd9xxx_dev == NULL || *wcd9xxx_dev_size == 0)
350 ret = -ENODEV;
351 pr_info("%s: Read codec idbytes & version\n"
352 "byte_0[%08x] byte_1[%08x] byte_2[%08x]\n"
353 " byte_3[%08x] version = %x\n", __func__,
354 wcd9xxx->idbyte[0], wcd9xxx->idbyte[1],
355 wcd9xxx->idbyte[2], wcd9xxx->idbyte[3],
356 wcd9xxx->version);
357exit:
358 return ret;
359}
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530360
361static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx, int irq)
362{
363 int ret;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530364 struct mfd_cell *wcd9xxx_dev = NULL;
365 int wcd9xxx_dev_size = 0;
366
367 mutex_init(&wcd9xxx->io_lock);
368 mutex_init(&wcd9xxx->xfer_lock);
369
370 mutex_init(&wcd9xxx->pm_lock);
371 wcd9xxx->wlock_holders = 0;
372 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
373 init_waitqueue_head(&wcd9xxx->pm_wq);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700374 pm_qos_add_request(&wcd9xxx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
375 PM_QOS_DEFAULT_VALUE);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530376
377 dev_set_drvdata(wcd9xxx->dev, wcd9xxx);
378
379 wcd9xxx_bring_up(wcd9xxx);
380
Kiran Kandi725f8492012-08-06 13:45:16 -0700381 if (wcd9xxx->irq != -1) {
382 ret = wcd9xxx_irq_init(wcd9xxx);
383 if (ret) {
384 pr_err("IRQ initialization failed\n");
385 goto err;
386 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530387 }
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700388 ret = wcd9xxx_check_codec_type(wcd9xxx, &wcd9xxx_dev,
389 &wcd9xxx_dev_size);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530390
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700391 if (ret < 0)
392 goto err_irq;
Joonwoo Parka7172112012-07-23 16:03:49 -0700393 ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx_dev, wcd9xxx_dev_size,
394 NULL, 0);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530395 if (ret != 0) {
396 dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
397 goto err_irq;
398 }
399 return ret;
400err_irq:
401 wcd9xxx_irq_exit(wcd9xxx);
402err:
403 wcd9xxx_bring_down(wcd9xxx);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700404 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530405 mutex_destroy(&wcd9xxx->pm_lock);
406 mutex_destroy(&wcd9xxx->io_lock);
407 mutex_destroy(&wcd9xxx->xfer_lock);
408 return ret;
409}
410
411static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
412{
413 wcd9xxx_irq_exit(wcd9xxx);
414 wcd9xxx_bring_down(wcd9xxx);
415 wcd9xxx_free_reset(wcd9xxx);
416 mutex_destroy(&wcd9xxx->pm_lock);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700417 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530418 mutex_destroy(&wcd9xxx->io_lock);
419 mutex_destroy(&wcd9xxx->xfer_lock);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700420 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
421 slim_remove_device(wcd9xxx->slim_slave);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530422 kfree(wcd9xxx);
423}
424
425
426#ifdef CONFIG_DEBUG_FS
427struct wcd9xxx *debugCodec;
428
429static struct dentry *debugfs_wcd9xxx_dent;
430static struct dentry *debugfs_peek;
431static struct dentry *debugfs_poke;
432
433static unsigned char read_data;
434
435static int codec_debug_open(struct inode *inode, struct file *file)
436{
437 file->private_data = inode->i_private;
438 return 0;
439}
440
441static int get_parameters(char *buf, long int *param1, int num_of_par)
442{
443 char *token;
444 int base, cnt;
445
446 token = strsep(&buf, " ");
447
448 for (cnt = 0; cnt < num_of_par; cnt++) {
449 if (token != NULL) {
450 if ((token[1] == 'x') || (token[1] == 'X'))
451 base = 16;
452 else
453 base = 10;
454
455 if (strict_strtoul(token, base, &param1[cnt]) != 0)
456 return -EINVAL;
457
458 token = strsep(&buf, " ");
459 } else
460 return -EINVAL;
461 }
462 return 0;
463}
464
465static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
466 size_t count, loff_t *ppos)
467{
468 char lbuf[8];
469
470 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
471 return simple_read_from_buffer(ubuf, count, ppos, lbuf,
472 strnlen(lbuf, 7));
473}
474
475
476static ssize_t codec_debug_write(struct file *filp,
477 const char __user *ubuf, size_t cnt, loff_t *ppos)
478{
479 char *access_str = filp->private_data;
480 char lbuf[32];
481 int rc;
482 long int param[5];
483
484 if (cnt > sizeof(lbuf) - 1)
485 return -EINVAL;
486
487 rc = copy_from_user(lbuf, ubuf, cnt);
488 if (rc)
489 return -EFAULT;
490
491 lbuf[cnt] = '\0';
492
493 if (!strncmp(access_str, "poke", 6)) {
494 /* write */
495 rc = get_parameters(lbuf, param, 2);
496 if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
497 (rc == 0))
498 wcd9xxx_interface_reg_write(debugCodec, param[0],
499 param[1]);
500 else
501 rc = -EINVAL;
502 } else if (!strncmp(access_str, "peek", 6)) {
503 /* read */
504 rc = get_parameters(lbuf, param, 1);
505 if ((param[0] <= 0x3FF) && (rc == 0))
506 read_data = wcd9xxx_interface_reg_read(debugCodec,
507 param[0]);
508 else
509 rc = -EINVAL;
510 }
511
512 if (rc == 0)
513 rc = cnt;
514 else
515 pr_err("%s: rc = %d\n", __func__, rc);
516
517 return rc;
518}
519
520static const struct file_operations codec_debug_ops = {
521 .open = codec_debug_open,
522 .write = codec_debug_write,
523 .read = codec_debug_read
524};
525#endif
526
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700527static int wcd9xxx_enable_supplies(struct wcd9xxx *wcd9xxx,
528 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530529{
530 int ret;
531 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530532 wcd9xxx->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
533 ARRAY_SIZE(pdata->regulator),
534 GFP_KERNEL);
535 if (!wcd9xxx->supplies) {
536 ret = -ENOMEM;
537 goto err;
538 }
539
Kiran Kandi725f8492012-08-06 13:45:16 -0700540 wcd9xxx->num_of_supplies = 0;
541 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
542 if (pdata->regulator[i].name) {
543 wcd9xxx->supplies[i].supply = pdata->regulator[i].name;
544 wcd9xxx->num_of_supplies++;
545 }
546 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530547
Kiran Kandi725f8492012-08-06 13:45:16 -0700548 ret = regulator_bulk_get(wcd9xxx->dev, wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530549 wcd9xxx->supplies);
550 if (ret != 0) {
551 dev_err(wcd9xxx->dev, "Failed to get supplies: err = %d\n",
552 ret);
553 goto err_supplies;
554 }
555
Kiran Kandi725f8492012-08-06 13:45:16 -0700556 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530557 ret = regulator_set_voltage(wcd9xxx->supplies[i].consumer,
558 pdata->regulator[i].min_uV, pdata->regulator[i].max_uV);
559 if (ret) {
560 pr_err("%s: Setting regulator voltage failed for "
561 "regulator %s err = %d\n", __func__,
562 wcd9xxx->supplies[i].supply, ret);
563 goto err_get;
564 }
565
566 ret = regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer,
567 pdata->regulator[i].optimum_uA);
568 if (ret < 0) {
569 pr_err("%s: Setting regulator optimum mode failed for "
570 "regulator %s err = %d\n", __func__,
571 wcd9xxx->supplies[i].supply, ret);
572 goto err_get;
573 }
574 }
575
Kiran Kandi725f8492012-08-06 13:45:16 -0700576 ret = regulator_bulk_enable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530577 wcd9xxx->supplies);
578 if (ret != 0) {
579 dev_err(wcd9xxx->dev, "Failed to enable supplies: err = %d\n",
580 ret);
581 goto err_configure;
582 }
583 return ret;
584
585err_configure:
Kiran Kandi725f8492012-08-06 13:45:16 -0700586 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530587 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
588 pdata->regulator[i].max_uV);
589 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
590 }
591err_get:
Kiran Kandi725f8492012-08-06 13:45:16 -0700592 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530593err_supplies:
594 kfree(wcd9xxx->supplies);
595err:
596 return ret;
597}
598
Venkat Sudhir49203862012-05-21 14:29:13 -0700599static void wcd9xxx_disable_supplies(struct wcd9xxx *wcd9xxx,
600 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530601{
602 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530603
Kiran Kandi725f8492012-08-06 13:45:16 -0700604 regulator_bulk_disable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530605 wcd9xxx->supplies);
Kiran Kandi725f8492012-08-06 13:45:16 -0700606 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530607 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
608 pdata->regulator[i].max_uV);
609 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
610 }
Kiran Kandi725f8492012-08-06 13:45:16 -0700611 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530612 kfree(wcd9xxx->supplies);
613}
614
615int wcd9xxx_get_intf_type(void)
616{
617 return wcd9xxx_intf;
618}
619EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
620
621struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
622{
623 u16 mask = 0x0f00;
624 int value = 0;
625 struct wcd9xxx_i2c *wcd9xxx = NULL;
626 value = ((reg & mask) >> 8) & 0x000f;
627 switch (value) {
628 case 0:
629 wcd9xxx = &wcd9xxx_modules[0];
630 break;
631 case 1:
632 wcd9xxx = &wcd9xxx_modules[1];
633 break;
634 case 2:
635 wcd9xxx = &wcd9xxx_modules[2];
636 break;
637 case 3:
638 wcd9xxx = &wcd9xxx_modules[3];
639 break;
640 default:
641 break;
642 }
643 return wcd9xxx;
644}
645
646int wcd9xxx_i2c_write_device(u16 reg, u8 *value,
647 u32 bytes)
648{
649
650 struct i2c_msg *msg;
651 int ret = 0;
652 u8 reg_addr = 0;
653 u8 data[bytes + 1];
654 struct wcd9xxx_i2c *wcd9xxx;
655
656 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
657 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
658 pr_err("failed to get device info\n");
659 return -ENODEV;
660 }
661 reg_addr = (u8)reg;
662 msg = &wcd9xxx->xfer_msg[0];
663 msg->addr = wcd9xxx->client->addr;
664 msg->len = bytes + 1;
665 msg->flags = 0;
666 data[0] = reg;
667 data[1] = *value;
668 msg->buf = data;
669 ret = i2c_transfer(wcd9xxx->client->adapter, wcd9xxx->xfer_msg, 1);
670 /* Try again if the write fails */
671 if (ret != 1) {
672 ret = i2c_transfer(wcd9xxx->client->adapter,
673 wcd9xxx->xfer_msg, 1);
674 if (ret != 1) {
675 pr_err("failed to write the device\n");
676 return ret;
677 }
678 }
679 pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
680 return 0;
681}
682
683
684int wcd9xxx_i2c_read_device(unsigned short reg,
685 int bytes, unsigned char *dest)
686{
687 struct i2c_msg *msg;
688 int ret = 0;
689 u8 reg_addr = 0;
690 struct wcd9xxx_i2c *wcd9xxx;
691 u8 i = 0;
692
693 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
694 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
695 pr_err("failed to get device info\n");
696 return -ENODEV;
697 }
698 for (i = 0; i < bytes; i++) {
699 reg_addr = (u8)reg++;
700 msg = &wcd9xxx->xfer_msg[0];
701 msg->addr = wcd9xxx->client->addr;
702 msg->len = 1;
703 msg->flags = 0;
704 msg->buf = &reg_addr;
705
706 msg = &wcd9xxx->xfer_msg[1];
707 msg->addr = wcd9xxx->client->addr;
708 msg->len = 1;
709 msg->flags = I2C_M_RD;
710 msg->buf = dest++;
711 ret = i2c_transfer(wcd9xxx->client->adapter,
712 wcd9xxx->xfer_msg, 2);
713
714 /* Try again if read fails first time */
715 if (ret != 2) {
716 ret = i2c_transfer(wcd9xxx->client->adapter,
717 wcd9xxx->xfer_msg, 2);
718 if (ret != 2) {
719 pr_err("failed to read wcd9xxx register\n");
720 return ret;
721 }
722 }
723 }
724 return 0;
725}
726
727int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
728 int bytes, void *dest, bool interface_reg)
729{
730 return wcd9xxx_i2c_read_device(reg, bytes, dest);
731}
732
733int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
734 int bytes, void *src, bool interface_reg)
735{
736 return wcd9xxx_i2c_write_device(reg, src, bytes);
737}
738
739static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
740 const struct i2c_device_id *id)
741{
742 struct wcd9xxx *wcd9xxx;
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700743 struct wcd9xxx_pdata *pdata;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530744 int val = 0;
745 int ret = 0;
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530746 int i2c_mode = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530747 static int device_id;
748
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530749 pr_info("%s\n", __func__);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700750 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
751 pr_info("tabla card is already detected in slimbus mode\n");
752 return -ENODEV;
753 }
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700754 pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530755 if (device_id > 0) {
756 wcd9xxx_modules[device_id++].client = client;
757 pr_info("probe for other slaves devices of tabla\n");
758 return ret;
759 }
760
761 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
762 if (wcd9xxx == NULL) {
763 pr_err("%s: error, allocation failed\n", __func__);
764 ret = -ENOMEM;
765 goto fail;
766 }
767
768 if (!pdata) {
769 dev_dbg(&client->dev, "no platform data?\n");
770 ret = -EINVAL;
771 goto fail;
772 }
773 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
774 dev_dbg(&client->dev, "can't talk I2C?\n");
775 ret = -EIO;
776 goto fail;
777 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530778 dev_set_drvdata(&client->dev, wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530779 wcd9xxx->dev = &client->dev;
780 wcd9xxx->reset_gpio = pdata->reset_gpio;
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700781 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530782 if (ret) {
783 pr_err("%s: Fail to enable Codec supplies\n", __func__);
784 goto err_codec;
785 }
786
787 usleep_range(5, 5);
788 ret = wcd9xxx_reset(wcd9xxx);
789 if (ret) {
790 pr_err("%s: Resetting Codec failed\n", __func__);
791 goto err_supplies;
792 }
793 wcd9xxx_modules[device_id++].client = client;
794
795 wcd9xxx->read_dev = wcd9xxx_i2c_read;
796 wcd9xxx->write_dev = wcd9xxx_i2c_write;
797 wcd9xxx->irq = pdata->irq;
798 wcd9xxx->irq_base = pdata->irq_base;
799
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530800 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
801 if (ret) {
802 pr_err("%s: error, initializing device failed\n", __func__);
803 goto err_device_init;
804 }
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530805
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700806 if ((wcd9xxx->idbyte[0] == 0x2) || (wcd9xxx->idbyte[0] == 0x1))
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530807 i2c_mode = TABLA_I2C_MODE;
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700808 else if (wcd9xxx->idbyte[0] == 0x0)
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530809 i2c_mode = SITAR_I2C_MODE;
810
811 ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
812
813 if ((ret < 0) || (val != i2c_mode))
814 pr_err("failed to read the wcd9xxx status ret = %d\n", ret);
815
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530816 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
817
818 return ret;
819err_device_init:
820 wcd9xxx_free_reset(wcd9xxx);
821err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -0700822 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530823err_codec:
824 kfree(wcd9xxx);
825fail:
826 return ret;
827}
828
829static int __devexit wcd9xxx_i2c_remove(struct i2c_client *client)
830{
831 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -0700832 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530833 pr_debug("exit\n");
834 wcd9xxx = dev_get_drvdata(&client->dev);
Venkat Sudhir49203862012-05-21 14:29:13 -0700835 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530836 wcd9xxx_device_exit(wcd9xxx);
837 return 0;
838}
839
Kiran Kandi725f8492012-08-06 13:45:16 -0700840#define CODEC_DT_MAX_PROP_SIZE 40
841static int wcd9xxx_dt_parse_vreg_info(struct device *dev,
842 struct wcd9xxx_regulator *vreg, const char *vreg_name)
843{
844 int len, ret = 0;
845 const __be32 *prop;
846 char prop_name[CODEC_DT_MAX_PROP_SIZE];
847 struct device_node *regnode = NULL;
848 u32 prop_val;
849
850 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
851 vreg_name);
852 regnode = of_parse_phandle(dev->of_node, prop_name, 0);
853
854 if (!regnode) {
855 dev_err(dev, "Looking up %s property in node %s failed",
856 prop_name, dev->of_node->full_name);
857 return -ENODEV;
858 }
859 vreg->name = vreg_name;
860
861 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
862 "qcom,%s-voltage", vreg_name);
863 prop = of_get_property(dev->of_node, prop_name, &len);
864
865 if (!prop || (len != (2 * sizeof(__be32)))) {
866 dev_err(dev, "%s %s property\n",
867 prop ? "invalid format" : "no", prop_name);
868 return -ENODEV;
869 } else {
870 vreg->min_uV = be32_to_cpup(&prop[0]);
871 vreg->max_uV = be32_to_cpup(&prop[1]);
872 }
873
874 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
875 "qcom,%s-current", vreg_name);
876
877 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
878 if (ret) {
879 dev_err(dev, "Looking up %s property in node %s failed",
880 prop_name, dev->of_node->full_name);
881 return -ENODEV;
882 }
883 vreg->optimum_uA = prop_val;
884
885 dev_info(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
886 vreg->min_uV, vreg->max_uV, vreg->optimum_uA);
887 return 0;
888}
889
890static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
891 struct wcd9xxx_micbias_setting *micbias)
892{
893 int ret = 0;
894 char prop_name[CODEC_DT_MAX_PROP_SIZE];
895 u32 prop_val;
896
897 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
898 "qcom,cdc-micbias-ldoh-v");
899 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
900 if (ret) {
901 dev_err(dev, "Looking up %s property in node %s failed",
902 prop_name, dev->of_node->full_name);
903 return -ENODEV;
904 }
905 micbias->ldoh_v = (u8)prop_val;
906
907 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
908 "qcom,cdc-micbias-cfilt1-mv");
909 ret = of_property_read_u32(dev->of_node, prop_name,
910 &micbias->cfilt1_mv);
911 if (ret) {
912 dev_err(dev, "Looking up %s property in node %s failed",
913 prop_name, dev->of_node->full_name);
914 return -ENODEV;
915 }
916
917 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
918 "qcom,cdc-micbias-cfilt2-mv");
919 ret = of_property_read_u32(dev->of_node, prop_name,
920 &micbias->cfilt2_mv);
921 if (ret) {
922 dev_err(dev, "Looking up %s property in node %s failed",
923 prop_name, dev->of_node->full_name);
924 return -ENODEV;
925 }
926
927 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
928 "qcom,cdc-micbias-cfilt3-mv");
929 ret = of_property_read_u32(dev->of_node, prop_name,
930 &micbias->cfilt3_mv);
931 if (ret) {
932 dev_err(dev, "Looking up %s property in node %s failed",
933 prop_name, dev->of_node->full_name);
934 return -ENODEV;
935 }
936
937 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
938 "qcom,cdc-micbias1-cfilt-sel");
939 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
940 if (ret) {
941 dev_err(dev, "Looking up %s property in node %s failed",
942 prop_name, dev->of_node->full_name);
943 return -ENODEV;
944 }
945 micbias->bias1_cfilt_sel = (u8)prop_val;
946
947 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
948 "qcom,cdc-micbias2-cfilt-sel");
949 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
950 if (ret) {
951 dev_err(dev, "Looking up %s property in node %s failed",
952 prop_name, dev->of_node->full_name);
953 return -ENODEV;
954 }
955 micbias->bias2_cfilt_sel = (u8)prop_val;
956
957 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
958 "qcom,cdc-micbias3-cfilt-sel");
959 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
960 if (ret) {
961 dev_err(dev, "Looking up %s property in node %s failed",
962 prop_name, dev->of_node->full_name);
963 return -ENODEV;
964 }
965 micbias->bias3_cfilt_sel = (u8)prop_val;
966
967 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
968 "qcom,cdc-micbias4-cfilt-sel");
969 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
970 if (ret) {
971 dev_err(dev, "Looking up %s property in node %s failed",
972 prop_name, dev->of_node->full_name);
973 return -ENODEV;
974 }
975 micbias->bias4_cfilt_sel = (u8)prop_val;
976
977 dev_dbg(dev, "ldoh_v %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u",
978 (u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv,
979 (u32)micbias->cfilt2_mv, (u32)micbias->cfilt3_mv);
980
981 dev_dbg(dev, "bias1_cfilt_sel %u bias2_cfilt_sel %u\n",
982 (u32)micbias->bias1_cfilt_sel, (u32)micbias->bias2_cfilt_sel);
983
984 dev_dbg(dev, "bias3_cfilt_sel %u bias4_cfilt_sel %u\n",
985 (u32)micbias->bias3_cfilt_sel, (u32)micbias->bias4_cfilt_sel);
986
987 return 0;
988}
989
990static int wcd9xxx_dt_parse_slim_interface_dev_info(struct device *dev,
991 struct slim_device *slim_ifd)
992{
993 int ret = 0;
994 struct property *prop;
995
996 ret = of_property_read_string(dev->of_node, "qcom,cdc-slim-ifd",
997 &slim_ifd->name);
998 if (ret) {
999 dev_err(dev, "Looking up %s property in node %s failed",
1000 "qcom,cdc-slim-ifd-dev", dev->of_node->full_name);
1001 return -ENODEV;
1002 }
1003 prop = of_find_property(dev->of_node,
1004 "qcom,cdc-slim-ifd-elemental-addr", NULL);
1005 if (!prop) {
1006 dev_err(dev, "Looking up %s property in node %s failed",
1007 "qcom,cdc-slim-ifd-elemental-addr",
1008 dev->of_node->full_name);
1009 return -ENODEV;
1010 } else if (prop->length != 6) {
1011 dev_err(dev, "invalid codec slim ifd addr. addr length = %d\n",
1012 prop->length);
1013 return -ENODEV;
1014 }
1015 memcpy(slim_ifd->e_addr, prop->value, 6);
1016
1017 return 0;
1018}
1019
1020static char *taiko_supplies[] = {
1021 "cdc-vdd-buck", "cdc-vdd-tx-h", "cdc-vdd-rx-h", "cdc-vddpx-1",
1022 "cdc-vdd-a-1p2v", "cdc-vddcx-1", "cdc-vddcx-2",
1023};
1024
1025static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev)
1026{
1027 struct wcd9xxx_pdata *pdata;
1028 int ret, i;
1029 char **codec_supplies;
1030 u32 num_of_supplies = 0;
1031
1032 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1033 if (!pdata) {
1034 dev_err(dev,
1035 "could not allocate memory for platform data\n");
1036 return NULL;
1037 }
1038
1039 if (!strcmp(dev_name(dev), "taiko-slim-pgd")) {
1040 codec_supplies = taiko_supplies;
1041 num_of_supplies = ARRAY_SIZE(taiko_supplies);
1042 } else {
1043 dev_err(dev, "%s unsupported device %s\n",
1044 __func__, dev_name(dev));
1045 goto err;
1046 }
1047
1048 if (num_of_supplies > ARRAY_SIZE(pdata->regulator)) {
1049 dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
1050 __func__, num_of_supplies, ARRAY_SIZE(pdata->regulator));
1051
1052 goto err;
1053 }
1054
1055 for (i = 0; i < num_of_supplies; i++) {
1056 ret = wcd9xxx_dt_parse_vreg_info(dev, &pdata->regulator[i],
1057 codec_supplies[i]);
1058 if (ret)
1059 goto err;
1060 }
1061
1062 ret = wcd9xxx_dt_parse_micbias_info(dev, &pdata->micbias);
1063 if (ret)
1064 goto err;
1065
1066 pdata->reset_gpio = of_get_named_gpio(dev->of_node,
1067 "qcom,cdc-reset-gpio", 0);
1068 if (pdata->reset_gpio < 0) {
1069 dev_err(dev, "Looking up %s property in node %s failed %d\n",
1070 "qcom, cdc-reset-gpio", dev->of_node->full_name,
1071 pdata->reset_gpio);
1072 goto err;
1073 }
1074 pdata->irq = -1;
1075
1076 ret = wcd9xxx_dt_parse_slim_interface_dev_info(dev,
1077 &pdata->slimbus_slave_device);
1078 if (ret)
1079 goto err;
1080 return pdata;
1081err:
1082 devm_kfree(dev, pdata);
1083 return NULL;
1084}
1085
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001086static int wcd9xxx_slim_get_laddr(struct slim_device *sb,
1087 const u8 *e_addr, u8 e_len, u8 *laddr)
1088{
1089 int ret;
1090 const unsigned long timeout = jiffies +
1091 msecs_to_jiffies(SLIMBUS_PRESENT_TIMEOUT);
1092
1093 do {
1094 ret = slim_get_logical_addr(sb, e_addr, e_len, laddr);
1095 if (!ret)
1096 break;
1097 /* Give SLIMBUS time to report present and be ready. */
1098 usleep_range(1000, 1000);
1099 pr_debug_ratelimited("%s: retyring get logical addr\n",
1100 __func__);
1101 } while time_before(jiffies, timeout);
1102
1103 return ret;
1104}
1105
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301106static int wcd9xxx_slim_probe(struct slim_device *slim)
1107{
1108 struct wcd9xxx *wcd9xxx;
1109 struct wcd9xxx_pdata *pdata;
1110 int ret = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301111
Kiran Kandi725f8492012-08-06 13:45:16 -07001112 if (slim->dev.of_node) {
1113 dev_info(&slim->dev, "Platform data from device tree\n");
1114 pdata = wcd9xxx_populate_dt_pdata(&slim->dev);
1115 slim->dev.platform_data = pdata;
1116
1117 } else {
1118 dev_info(&slim->dev, "Platform data from board file\n");
1119 pdata = slim->dev.platform_data;
1120 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301121
1122 if (!pdata) {
1123 dev_err(&slim->dev, "Error, no platform data\n");
1124 ret = -EINVAL;
1125 goto err;
1126 }
1127
1128 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
1129 if (wcd9xxx == NULL) {
1130 pr_err("%s: error, allocation failed\n", __func__);
1131 ret = -ENOMEM;
1132 goto err;
1133 }
1134 if (!slim->ctrl) {
1135 pr_err("Error, no SLIMBUS control data\n");
1136 ret = -EINVAL;
1137 goto err_codec;
1138 }
1139 wcd9xxx->slim = slim;
1140 slim_set_clientdata(slim, wcd9xxx);
1141 wcd9xxx->reset_gpio = pdata->reset_gpio;
1142 wcd9xxx->dev = &slim->dev;
1143
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -07001144 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301145 if (ret)
1146 goto err_codec;
1147 usleep_range(5, 5);
1148
1149 ret = wcd9xxx_reset(wcd9xxx);
1150 if (ret) {
1151 pr_err("%s: Resetting Codec failed\n", __func__);
1152 goto err_supplies;
1153 }
1154
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001155 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
1156 ARRAY_SIZE(wcd9xxx->slim->e_addr),
1157 &wcd9xxx->slim->laddr);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301158 if (ret) {
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001159 pr_err("%s: failed to get slimbus %s logical address: %d\n",
1160 __func__, wcd9xxx->slim->name, ret);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301161 goto err_reset;
1162 }
1163 wcd9xxx->read_dev = wcd9xxx_slim_read_device;
1164 wcd9xxx->write_dev = wcd9xxx_slim_write_device;
1165 wcd9xxx->irq = pdata->irq;
1166 wcd9xxx->irq_base = pdata->irq_base;
1167 wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
1168
Joonwoo Park51d89662012-08-28 17:21:24 -07001169 if (pdata->num_irqs < TABLA_NUM_IRQS)
1170 pr_warn("%s: Not enough interrupt lines allocated\n", __func__);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301171
1172 wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
1173
1174 ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
1175 if (ret) {
1176 pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
1177 goto err_reset;
1178 }
1179
Joonwoo Park3c5b2df2012-08-28 15:36:55 -07001180 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim_slave,
1181 wcd9xxx->slim_slave->e_addr,
1182 ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
1183 &wcd9xxx->slim_slave->laddr);
1184 if (ret) {
1185 pr_err("%s: failed to get slimbus %s logical address: %d\n",
1186 __func__, wcd9xxx->slim->name, ret);
1187 goto err_slim_add;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301188 }
1189 wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
1190 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_SLIMBUS;
1191
1192 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
1193 if (ret) {
1194 pr_err("%s: error, initializing device failed\n", __func__);
1195 goto err_slim_add;
1196 }
Joonwoo Parka7172112012-07-23 16:03:49 -07001197
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301198 wcd9xxx_init_slimslave(wcd9xxx, wcd9xxx_pgd_la);
Joonwoo Parka7172112012-07-23 16:03:49 -07001199
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301200#ifdef CONFIG_DEBUG_FS
1201 debugCodec = wcd9xxx;
1202
1203 debugfs_wcd9xxx_dent = debugfs_create_dir
1204 ("wcd9310_slimbus_interface_device", 0);
1205 if (!IS_ERR(debugfs_wcd9xxx_dent)) {
1206 debugfs_peek = debugfs_create_file("peek",
1207 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1208 (void *) "peek", &codec_debug_ops);
1209
1210 debugfs_poke = debugfs_create_file("poke",
1211 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1212 (void *) "poke", &codec_debug_ops);
1213 }
1214#endif
1215
1216 return ret;
1217
1218err_slim_add:
1219 slim_remove_device(wcd9xxx->slim_slave);
1220err_reset:
1221 wcd9xxx_free_reset(wcd9xxx);
1222err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -07001223 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301224err_codec:
1225 kfree(wcd9xxx);
1226err:
1227 return ret;
1228}
1229static int wcd9xxx_slim_remove(struct slim_device *pdev)
1230{
1231 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -07001232 struct wcd9xxx_pdata *pdata = pdev->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301233
1234#ifdef CONFIG_DEBUG_FS
1235 debugfs_remove(debugfs_peek);
1236 debugfs_remove(debugfs_poke);
1237 debugfs_remove(debugfs_wcd9xxx_dent);
1238#endif
1239 wcd9xxx = slim_get_devicedata(pdev);
1240 wcd9xxx_deinit_slimslave(wcd9xxx);
1241 slim_remove_device(wcd9xxx->slim_slave);
Venkat Sudhir49203862012-05-21 14:29:13 -07001242 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301243 wcd9xxx_device_exit(wcd9xxx);
1244 return 0;
1245}
1246
1247static int wcd9xxx_resume(struct wcd9xxx *wcd9xxx)
1248{
1249 int ret = 0;
1250
1251 pr_debug("%s: enter\n", __func__);
1252 mutex_lock(&wcd9xxx->pm_lock);
1253 if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1254 pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
1255 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1256 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
1257 } else {
1258 pr_warn("%s: system is already awake, state %d wlock %d\n",
1259 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1260 }
1261 mutex_unlock(&wcd9xxx->pm_lock);
1262 wake_up_all(&wcd9xxx->pm_wq);
1263
1264 return ret;
1265}
1266
1267static int wcd9xxx_slim_resume(struct slim_device *sldev)
1268{
1269 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1270 return wcd9xxx_resume(wcd9xxx);
1271}
1272
1273static int wcd9xxx_i2c_resume(struct i2c_client *i2cdev)
1274{
1275 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301276 if (wcd9xxx)
1277 return wcd9xxx_resume(wcd9xxx);
1278 else
1279 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301280}
1281
1282static int wcd9xxx_suspend(struct wcd9xxx *wcd9xxx, pm_message_t pmesg)
1283{
1284 int ret = 0;
1285
1286 pr_debug("%s: enter\n", __func__);
Stephen Boyd2fcabf92012-05-30 10:41:11 -07001287 /*
1288 * pm_qos_update_request() can be called after this suspend chain call
1289 * started. thus suspend can be called while lock is being held
1290 */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301291 mutex_lock(&wcd9xxx->pm_lock);
1292 if (wcd9xxx->pm_state == WCD9XXX_PM_SLEEPABLE) {
1293 pr_debug("%s: suspending system, state %d, wlock %d\n",
1294 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1295 wcd9xxx->pm_state = WCD9XXX_PM_ASLEEP;
1296 } else if (wcd9xxx->pm_state == WCD9XXX_PM_AWAKE) {
1297 /* unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
1298 * then set to WCD9XXX_PM_ASLEEP */
1299 pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
1300 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1301 mutex_unlock(&wcd9xxx->pm_lock);
1302 if (!(wait_event_timeout(wcd9xxx->pm_wq,
1303 wcd9xxx_pm_cmpxchg(wcd9xxx,
1304 WCD9XXX_PM_SLEEPABLE,
1305 WCD9XXX_PM_ASLEEP) ==
1306 WCD9XXX_PM_SLEEPABLE,
1307 HZ))) {
1308 pr_debug("%s: suspend failed state %d, wlock %d\n",
1309 __func__, wcd9xxx->pm_state,
1310 wcd9xxx->wlock_holders);
1311 ret = -EBUSY;
1312 } else {
1313 pr_debug("%s: done, state %d, wlock %d\n", __func__,
1314 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1315 }
1316 mutex_lock(&wcd9xxx->pm_lock);
1317 } else if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1318 pr_warn("%s: system is already suspended, state %d, wlock %dn",
1319 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1320 }
1321 mutex_unlock(&wcd9xxx->pm_lock);
1322
1323 return ret;
1324}
1325
1326static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
1327{
1328 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1329 return wcd9xxx_suspend(wcd9xxx, pmesg);
1330}
1331
1332static int wcd9xxx_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
1333{
1334 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301335 if (wcd9xxx)
1336 return wcd9xxx_suspend(wcd9xxx, pmesg);
1337 else
1338 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301339}
1340
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301341static const struct slim_device_id sitar_slimtest_id[] = {
1342 {"sitar-slim", 0},
1343 {}
1344};
1345static struct slim_driver sitar_slim_driver = {
1346 .driver = {
1347 .name = "sitar-slim",
1348 .owner = THIS_MODULE,
1349 },
1350 .probe = wcd9xxx_slim_probe,
1351 .remove = wcd9xxx_slim_remove,
1352 .id_table = sitar_slimtest_id,
1353 .resume = wcd9xxx_slim_resume,
1354 .suspend = wcd9xxx_slim_suspend,
1355};
1356
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001357static const struct slim_device_id sitar1p1_slimtest_id[] = {
1358 {"sitar1p1-slim", 0},
1359 {}
1360};
1361static struct slim_driver sitar1p1_slim_driver = {
1362 .driver = {
1363 .name = "sitar1p1-slim",
1364 .owner = THIS_MODULE,
1365 },
1366 .probe = wcd9xxx_slim_probe,
1367 .remove = wcd9xxx_slim_remove,
1368 .id_table = sitar1p1_slimtest_id,
1369 .resume = wcd9xxx_slim_resume,
1370 .suspend = wcd9xxx_slim_suspend,
1371};
1372
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301373static const struct slim_device_id slimtest_id[] = {
1374 {"tabla-slim", 0},
1375 {}
1376};
1377
1378static struct slim_driver tabla_slim_driver = {
1379 .driver = {
1380 .name = "tabla-slim",
1381 .owner = THIS_MODULE,
1382 },
1383 .probe = wcd9xxx_slim_probe,
1384 .remove = wcd9xxx_slim_remove,
1385 .id_table = slimtest_id,
1386 .resume = wcd9xxx_slim_resume,
1387 .suspend = wcd9xxx_slim_suspend,
1388};
1389
1390static const struct slim_device_id slimtest2x_id[] = {
1391 {"tabla2x-slim", 0},
1392 {}
1393};
1394
1395static struct slim_driver tabla2x_slim_driver = {
1396 .driver = {
1397 .name = "tabla2x-slim",
1398 .owner = THIS_MODULE,
1399 },
1400 .probe = wcd9xxx_slim_probe,
1401 .remove = wcd9xxx_slim_remove,
1402 .id_table = slimtest2x_id,
1403 .resume = wcd9xxx_slim_resume,
1404 .suspend = wcd9xxx_slim_suspend,
1405};
1406
Joonwoo Parka7172112012-07-23 16:03:49 -07001407static const struct slim_device_id taiko_slimtest_id[] = {
Kiran Kandi725f8492012-08-06 13:45:16 -07001408 {"taiko-slim-pgd", 0},
Joonwoo Parka7172112012-07-23 16:03:49 -07001409 {}
1410};
1411
1412static struct slim_driver taiko_slim_driver = {
1413 .driver = {
1414 .name = "taiko-slim",
1415 .owner = THIS_MODULE,
1416 },
1417 .probe = wcd9xxx_slim_probe,
1418 .remove = wcd9xxx_slim_remove,
1419 .id_table = taiko_slimtest_id,
1420 .resume = wcd9xxx_slim_resume,
1421 .suspend = wcd9xxx_slim_suspend,
1422};
1423
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301424#define WCD9XXX_I2C_TOP_LEVEL 0
1425#define WCD9XXX_I2C_ANALOG 1
1426#define WCD9XXX_I2C_DIGITAL_1 2
1427#define WCD9XXX_I2C_DIGITAL_2 3
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301428
1429static struct i2c_device_id tabla_id_table[] = {
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301430 {"tabla top level", WCD9XXX_I2C_TOP_LEVEL},
1431 {"tabla analog", WCD9XXX_I2C_ANALOG},
1432 {"tabla digital1", WCD9XXX_I2C_DIGITAL_1},
1433 {"tabla digital2", WCD9XXX_I2C_DIGITAL_2},
1434 {}
1435};
1436MODULE_DEVICE_TABLE(i2c, tabla_id_table);
1437
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301438static struct i2c_driver tabla_i2c_driver = {
1439 .driver = {
1440 .owner = THIS_MODULE,
1441 .name = "tabla-i2c-core",
1442 },
1443 .id_table = tabla_id_table,
1444 .probe = wcd9xxx_i2c_probe,
1445 .remove = __devexit_p(wcd9xxx_i2c_remove),
1446 .resume = wcd9xxx_i2c_resume,
1447 .suspend = wcd9xxx_i2c_suspend,
1448};
1449
1450static int __init wcd9xxx_init(void)
1451{
Joonwoo Parka7172112012-07-23 16:03:49 -07001452 int ret1, ret2, ret3, ret4, ret5, ret6;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301453
1454 ret1 = slim_driver_register(&tabla_slim_driver);
1455 if (ret1 != 0)
1456 pr_err("Failed to register tabla SB driver: %d\n", ret1);
1457
1458 ret2 = slim_driver_register(&tabla2x_slim_driver);
1459 if (ret2 != 0)
1460 pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
1461
1462 ret3 = i2c_add_driver(&tabla_i2c_driver);
1463 if (ret3 != 0)
1464 pr_err("failed to add the I2C driver\n");
1465
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301466 ret4 = slim_driver_register(&sitar_slim_driver);
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001467 if (ret4 != 0)
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301468 pr_err("Failed to register sitar SB driver: %d\n", ret4);
1469
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001470 ret5 = slim_driver_register(&sitar1p1_slim_driver);
1471 if (ret5 != 0)
1472 pr_err("Failed to register sitar SB driver: %d\n", ret5);
1473
Joonwoo Parka7172112012-07-23 16:03:49 -07001474 ret6 = slim_driver_register(&taiko_slim_driver);
1475 if (ret6 != 0)
1476 pr_err("Failed to register taiko SB driver: %d\n", ret6);
1477
1478 return (ret1 && ret2 && ret3 && ret4 && ret5 && ret6) ? -1 : 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301479}
1480module_init(wcd9xxx_init);
1481
1482static void __exit wcd9xxx_exit(void)
1483{
1484}
1485module_exit(wcd9xxx_exit);
1486
1487MODULE_DESCRIPTION("Codec core driver");
1488MODULE_VERSION("1.0");
1489MODULE_LICENSE("GPL v2");