blob: 9736c43c365bf09b2363ca26143dfa64adcd8e9b [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05302/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303 */
4
5#include <linux/kernel.h>
6#include <linux/module.h>
7#include <linux/of_device.h>
8#include <linux/slab.h>
9#include <linux/ratelimit.h>
10#include <linux/mfd/core.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053011#include <linux/delay.h>
12#include <linux/gpio.h>
13#include <linux/debugfs.h>
14#include <linux/i2c.h>
15#include <linux/regmap.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053016#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053017#include <sound/soc.h>
Meng Wang11a25cf2018-10-31 14:11:26 +080018#include <asoc/core.h>
19#include <asoc/pdata.h>
20#include <asoc/msm-cdc-pinctrl.h>
21#include <asoc/msm-cdc-supply.h>
22#include <asoc/wcd9xxx-irq.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +053023#include "wcd9xxx-utils.h"
Meng Wang11a25cf2018-10-31 14:11:26 +080024#include <asoc/wcd9xxx-regmap.h>
25#include <asoc/wcd9xxx-slimslave.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053026
27#define WCD9XXX_REGISTER_START_OFFSET 0x800
28#define WCD9XXX_SLIM_RW_MAX_TRIES 3
29#define SLIMBUS_PRESENT_TIMEOUT 100
30
31#define MAX_WCD9XXX_DEVICE 4
32#define WCD9XXX_I2C_GSBI_SLAVE_ID "3-000d"
33#define WCD9XXX_I2C_TOP_SLAVE_ADDR 0x0d
34#define WCD9XXX_ANALOG_I2C_SLAVE_ADDR 0x77
35#define WCD9XXX_DIGITAL1_I2C_SLAVE_ADDR 0x66
36#define WCD9XXX_DIGITAL2_I2C_SLAVE_ADDR 0x55
37#define WCD9XXX_I2C_TOP_LEVEL 0
38#define WCD9XXX_I2C_ANALOG 1
39#define WCD9XXX_I2C_DIGITAL_1 2
40#define WCD9XXX_I2C_DIGITAL_2 3
41
42/*
43 * Number of return values needs to be checked for each
44 * registration of Slimbus of I2C bus for each codec
45 */
Karthikeyan Mani57d3b662017-12-11 15:37:06 -080046#define NUM_WCD9XXX_REG_RET 5
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053047
48#define SLIM_USR_MC_REPEAT_CHANGE_VALUE 0x0
49#define SLIM_REPEAT_WRITE_MAX_SLICE 16
50#define REG_BYTES 2
51#define VAL_BYTES 1
52#define WCD9XXX_PAGE_NUM(reg) (((reg) >> 8) & 0xff)
53#define WCD9XXX_PAGE_SIZE 256
54
55struct wcd9xxx_i2c {
56 struct i2c_client *client;
57 struct i2c_msg xfer_msg[2];
58 struct mutex xfer_lock;
59 int mod_id;
60};
61
62static struct regmap_config wcd9xxx_base_regmap_config = {
63 .reg_bits = 16,
64 .val_bits = 8,
65 .can_multi_write = true,
66};
67
68static struct regmap_config wcd9xxx_i2c_base_regmap_config = {
69 .reg_bits = 16,
70 .val_bits = 8,
71 .can_multi_write = false,
72 .use_single_rw = true,
73};
74
75static u8 wcd9xxx_pgd_la;
76static u8 wcd9xxx_inf_la;
77
78static const int wcd9xxx_cdc_types[] = {
79 [WCD9XXX] = WCD9XXX,
80 [WCD9330] = WCD9330,
81 [WCD9335] = WCD9335,
82 [WCD934X] = WCD934X,
83};
84
85static const struct of_device_id wcd9xxx_of_match[] = {
Karthikeyan Mani57d3b662017-12-11 15:37:06 -080086 { .compatible = "qcom,tavil-i2c",
87 .data = (void *)&wcd9xxx_cdc_types[WCD934X]},
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053088 { .compatible = "qcom,tasha-i2c-pgd",
89 .data = (void *)&wcd9xxx_cdc_types[WCD9335]},
90 { .compatible = "qcom,wcd9xxx-i2c",
91 .data = (void *)&wcd9xxx_cdc_types[WCD9330]},
92 { }
93};
94MODULE_DEVICE_TABLE(of, wcd9xxx_of_match);
95
96static int wcd9xxx_slim_device_up(struct slim_device *sldev);
97static int wcd9xxx_slim_device_down(struct slim_device *sldev);
98
99struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
100
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +0530101/*
102 * wcd9xxx_vote_ondemand_regulator: Initialize codec dynamic supplies
103 *
104 * @wcd9xxx: Pointer to wcd9xxx structure
105 * @wcd9xxx_pdata: Pointer to wcd9xxx_pdata structure
106 * @supply_name: supply parameter to initialize regulator
107 * @enable: flag to initialize/uninitialize supply
108 *
109 * Return error code if supply init is failed
110 */
111int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx,
112 struct wcd9xxx_pdata *pdata,
113 const char *supply_name,
114 bool enable)
115{
116 int i, rc, index = -EINVAL;
117
118 pr_debug("%s: enable %d\n", __func__, enable);
119
120 for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
121 if (pdata->regulator[i].ondemand &&
122 wcd9xxx->supplies[i].supply &&
123 !strcmp(wcd9xxx->supplies[i].supply, supply_name)) {
124 index = i;
125 break;
126 }
127 }
128
129 if (index < 0) {
130 pr_err("%s: no matching regulator found\n", __func__);
131 return -EINVAL;
132 }
133
134 if (enable) {
135 rc = regulator_set_voltage(wcd9xxx->supplies[index].consumer,
136 pdata->regulator[index].min_uV,
137 pdata->regulator[index].max_uV);
138 if (rc) {
139 pr_err("%s: set regulator voltage failed for %s, err:%d\n",
140 __func__, supply_name, rc);
141 return rc;
142 }
143 rc = regulator_set_load(wcd9xxx->supplies[index].consumer,
144 pdata->regulator[index].optimum_uA);
145 if (rc < 0) {
146 pr_err("%s: set regulator optimum mode failed for %s, err:%d\n",
147 __func__, supply_name, rc);
148 return rc;
149 }
150 } else {
151 regulator_set_voltage(wcd9xxx->supplies[index].consumer, 0,
152 pdata->regulator[index].max_uV);
153 regulator_set_load(wcd9xxx->supplies[index].consumer, 0);
154 }
155
156 return 0;
157}
158EXPORT_SYMBOL(wcd9xxx_vote_ondemand_regulator);
159
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530160static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx,
161 const void *data, size_t count)
162{
163 unsigned int reg;
164 struct device *dev;
165 u8 val[WCD9XXX_PAGE_SIZE];
166 int ret = 0;
167 int i = 0;
168 int n = 0;
169 unsigned int page_num;
170 size_t num_regs = (count / (REG_BYTES + VAL_BYTES));
171 struct wcd9xxx_reg_val *bulk_reg;
172 u8 *buf;
173
174 dev = wcd9xxx->dev;
175 if (!data) {
176 dev_err(dev, "%s: data is NULL\n", __func__);
177 return -EINVAL;
178 }
179 if (num_regs == 0)
180 return -EINVAL;
181
182 bulk_reg = kzalloc(num_regs * (sizeof(struct wcd9xxx_reg_val)),
183 GFP_KERNEL);
184 if (!bulk_reg)
185 return -ENOMEM;
186
187 buf = (u8 *)data;
188 reg = *(u16 *)buf;
189 page_num = WCD9XXX_PAGE_NUM(reg);
190 for (i = 0, n = 0; n < num_regs; i++, n++) {
191 reg = *(u16 *)buf;
192 if (page_num != WCD9XXX_PAGE_NUM(reg)) {
193 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
194 i, false);
195 page_num = WCD9XXX_PAGE_NUM(reg);
196 i = 0;
197 }
198 buf += REG_BYTES;
199 val[i] = *buf;
200 buf += VAL_BYTES;
201 bulk_reg[i].reg = reg;
202 bulk_reg[i].buf = &val[i];
203 bulk_reg[i].bytes = 1;
204 }
205 ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
206 i, false);
207 if (ret)
208 dev_err(dev, "%s: error writing bulk regs\n",
209 __func__);
210
211 kfree(bulk_reg);
212 return ret;
213}
214
215/*
216 * wcd9xxx_interface_reg_read: Read slim interface registers
217 *
218 * @wcd9xxx: Pointer to wcd9xxx structure
219 * @reg: register adderss
220 *
221 * Returns register value in success and negative error code in case of failure
222 */
223int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
224{
225 u8 val;
226 int ret;
227
228 mutex_lock(&wcd9xxx->io_lock);
229 ret = wcd9xxx->read_dev(wcd9xxx, reg, 1, (void *)&val,
230 true);
231 if (ret < 0)
232 dev_err(wcd9xxx->dev, "%s: Codec read 0x%x failed\n",
233 __func__, reg);
234 else
235 dev_dbg(wcd9xxx->dev, "%s: Read 0x%02x from 0x%x\n",
236 __func__, val, reg);
237
238 mutex_unlock(&wcd9xxx->io_lock);
239
240 if (ret < 0)
241 return ret;
242 else
243 return val;
244}
245EXPORT_SYMBOL(wcd9xxx_interface_reg_read);
246
247/*
248 * wcd9xxx_interface_reg_write: Write slim interface registers
249 *
250 * @wcd9xxx: Pointer to wcd9xxx structure
251 * @reg: register adderss
252 * @val: value of the register to be written
253 *
254 * Returns 0 for success and negative error code in case of failure
255 */
256int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
257 u8 val)
258{
259 int ret;
260
261 mutex_lock(&wcd9xxx->io_lock);
262 ret = wcd9xxx->write_dev(wcd9xxx, reg, 1, (void *)&val, true);
263 dev_dbg(wcd9xxx->dev, "%s: Write %02x to 0x%x ret(%d)\n",
264 __func__, val, reg, ret);
265 mutex_unlock(&wcd9xxx->io_lock);
266
267 return ret;
268}
269EXPORT_SYMBOL(wcd9xxx_interface_reg_write);
270
271static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
272 int bytes, void *dest, bool interface)
273{
274 int ret;
275 struct slim_ele_access msg;
276 int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
277
278 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
279 msg.num_bytes = bytes;
280 msg.comp = NULL;
281
282 if (!wcd9xxx->dev_up) {
283 dev_dbg_ratelimited(
Banajit Goswamif6bc7132017-10-20 22:29:42 -0700284 wcd9xxx->dev, "%s: No read allowed. dev_up = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530285 __func__, wcd9xxx->dev_up);
286 return 0;
287 }
288
289 while (1) {
290 mutex_lock(&wcd9xxx->xfer_lock);
291 ret = slim_request_val_element(interface ?
292 wcd9xxx->slim_slave : wcd9xxx->slim,
293 &msg, dest, bytes);
294 mutex_unlock(&wcd9xxx->xfer_lock);
295 if (likely(ret == 0) || (--slim_read_tries == 0))
296 break;
297 usleep_range(5000, 5100);
298 }
299
300 if (ret)
301 dev_err(wcd9xxx->dev, "%s: Error, Codec read failed (%d)\n",
302 __func__, ret);
303
304 return ret;
305}
306
307/*
308 * Interface specifies whether the write is to the interface or general
309 * registers.
310 */
311static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
312 unsigned short reg, int bytes, void *src, bool interface)
313{
314 int ret;
315 struct slim_ele_access msg;
316 int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
317
318 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
319 msg.num_bytes = bytes;
320 msg.comp = NULL;
321
322 if (!wcd9xxx->dev_up) {
323 dev_dbg_ratelimited(
Banajit Goswamif6bc7132017-10-20 22:29:42 -0700324 wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530325 __func__, wcd9xxx->dev_up);
326 return 0;
327 }
328
329 while (1) {
330 mutex_lock(&wcd9xxx->xfer_lock);
331 ret = slim_change_val_element(interface ?
332 wcd9xxx->slim_slave : wcd9xxx->slim,
333 &msg, src, bytes);
334 mutex_unlock(&wcd9xxx->xfer_lock);
335 if (likely(ret == 0) || (--slim_write_tries == 0))
336 break;
337 usleep_range(5000, 5100);
338 }
339
340 if (ret)
341 pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
342
343 return ret;
344}
345
346static int wcd9xxx_slim_get_allowed_slice(struct wcd9xxx *wcd9xxx,
347 int bytes)
348{
349 int allowed_sz = bytes;
350
351 if (likely(bytes == SLIM_REPEAT_WRITE_MAX_SLICE))
352 allowed_sz = 16;
353 else if (bytes >= 12)
354 allowed_sz = 12;
355 else if (bytes >= 8)
356 allowed_sz = 8;
357 else if (bytes >= 6)
358 allowed_sz = 6;
359 else if (bytes >= 4)
360 allowed_sz = 4;
361 else
362 allowed_sz = bytes;
363
364 return allowed_sz;
365}
366
367/*
368 * wcd9xxx_slim_write_repeat: Write the same register with multiple values
369 * @wcd9xxx: handle to wcd core
370 * @reg: register to be written
371 * @bytes: number of bytes to be written to reg
372 * @src: buffer with data content to be written to reg
373 * This API will write reg with bytes from src in a single slimbus
374 * transaction. All values from 1 to 16 are supported by this API.
375 */
376int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg,
377 int bytes, void *src)
378{
379 int ret = 0, bytes_to_write = bytes, bytes_allowed;
380 struct slim_ele_access slim_msg;
381
382 mutex_lock(&wcd9xxx->io_lock);
Meng Wangd6107d02018-11-16 13:06:16 +0800383 if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) {
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530384 ret = wcd9xxx_page_write(wcd9xxx, &reg);
385 if (ret)
386 goto done;
387 }
388
389 slim_msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
390 slim_msg.comp = NULL;
391
392 if (unlikely(bytes > SLIM_REPEAT_WRITE_MAX_SLICE)) {
393 dev_err(wcd9xxx->dev, "%s: size %d not supported\n",
394 __func__, bytes);
395 ret = -EINVAL;
396 goto done;
397 }
398
399 if (!wcd9xxx->dev_up) {
400 dev_dbg_ratelimited(
Banajit Goswamif6bc7132017-10-20 22:29:42 -0700401 wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530402 __func__, wcd9xxx->dev_up);
403 ret = 0;
404 goto done;
405 }
406
407 while (bytes_to_write > 0) {
408 bytes_allowed = wcd9xxx_slim_get_allowed_slice(wcd9xxx,
409 bytes_to_write);
410
411 slim_msg.num_bytes = bytes_allowed;
412 mutex_lock(&wcd9xxx->xfer_lock);
413 ret = slim_user_msg(wcd9xxx->slim, wcd9xxx->slim->laddr,
414 SLIM_MSG_MT_DEST_REFERRED_USER,
415 SLIM_USR_MC_REPEAT_CHANGE_VALUE,
416 &slim_msg, src, bytes_allowed);
417 mutex_unlock(&wcd9xxx->xfer_lock);
418
419 if (ret) {
420 dev_err(wcd9xxx->dev, "%s: failed, ret = %d\n",
421 __func__, ret);
422 break;
423 }
424
425 bytes_to_write = bytes_to_write - bytes_allowed;
426 src = ((u8 *)src) + bytes_allowed;
427 }
428
429done:
430 mutex_unlock(&wcd9xxx->io_lock);
431
432 return ret;
433}
434EXPORT_SYMBOL(wcd9xxx_slim_write_repeat);
435
436/*
437 * wcd9xxx_slim_reserve_bw: API to reserve the slimbus bandwidth
438 * @wcd9xxx: Handle to the wcd9xxx core
439 * @bw_ops: value of the bandwidth that is requested
440 * @commit: Flag to indicate if bandwidth change is to be committed
441 * right away
442 */
443int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx,
444 u32 bw_ops, bool commit)
445{
446 if (!wcd9xxx || !wcd9xxx->slim) {
447 pr_err("%s: Invalid handle to %s\n",
448 __func__,
449 (!wcd9xxx) ? "wcd9xxx" : "slim_device");
450 return -EINVAL;
451 }
452
453 return slim_reservemsg_bw(wcd9xxx->slim, bw_ops, commit);
454}
455EXPORT_SYMBOL(wcd9xxx_slim_reserve_bw);
456
457/*
458 * wcd9xxx_slim_bulk_write: API to write multiple registers with one descriptor
459 * @wcd9xxx: Handle to the wcd9xxx core
460 * @wcd9xxx_reg_val: structure holding register and values to be written
461 * @size: Indicates number of messages to be written with one descriptor
462 * @is_interface: Indicates whether the register is for slim interface or for
463 * general registers.
464 * @return: returns 0 if success or error information to the caller in case
465 * of failure.
466 */
467int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx,
468 struct wcd9xxx_reg_val *bulk_reg,
469 unsigned int size, bool is_interface)
470{
471 int ret, i;
472 struct slim_val_inf *msgs;
473 unsigned short reg;
474
475 if (!bulk_reg || !size || !wcd9xxx) {
476 pr_err("%s: Invalid parameters\n", __func__);
477 return -EINVAL;
478 }
479
480 if (!wcd9xxx->dev_up) {
481 dev_dbg_ratelimited(
Banajit Goswamif6bc7132017-10-20 22:29:42 -0700482 wcd9xxx->dev, "%s: No write allowed. dev_up = %d\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530483 __func__, wcd9xxx->dev_up);
484 return 0;
485 }
486
487 msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL);
488 if (!msgs) {
489 ret = -ENOMEM;
490 goto mem_fail;
491 }
492
493 mutex_lock(&wcd9xxx->io_lock);
494 reg = bulk_reg->reg;
495 for (i = 0; i < size; i++) {
496 msgs[i].start_offset = WCD9XXX_REGISTER_START_OFFSET +
497 (bulk_reg->reg & 0xFF);
498 msgs[i].num_bytes = bulk_reg->bytes;
499 msgs[i].wbuf = bulk_reg->buf;
500 bulk_reg++;
501 }
502 ret = wcd9xxx_page_write(wcd9xxx, &reg);
503 if (ret) {
504 pr_err("%s: Page write error for reg: 0x%x\n",
505 __func__, reg);
506 goto err;
507 }
508
509 ret = slim_bulk_msg_write(is_interface ?
510 wcd9xxx->slim_slave : wcd9xxx->slim,
511 SLIM_MSG_MT_CORE,
512 SLIM_MSG_MC_CHANGE_VALUE, msgs, size,
513 NULL, NULL);
514 if (ret)
515 pr_err("%s: Error, Codec bulk write failed (%d)\n",
516 __func__, ret);
517 /* 100 usec sleep is needed as per HW requirement */
518 usleep_range(100, 110);
519err:
520 mutex_unlock(&wcd9xxx->io_lock);
521 kfree(msgs);
522mem_fail:
523 return ret;
524}
525EXPORT_SYMBOL(wcd9xxx_slim_bulk_write);
526
527static int wcd9xxx_num_irq_regs(const struct wcd9xxx *wcd9xxx)
528{
529 return (wcd9xxx->codec_type->num_irqs / 8) +
530 ((wcd9xxx->codec_type->num_irqs % 8) ? 1 : 0);
531}
532
533static int wcd9xxx_regmap_init_cache(struct wcd9xxx *wcd9xxx)
534{
535 struct regmap_config *regmap_config;
536 int rc;
537
538 regmap_config = wcd9xxx_get_regmap_config(wcd9xxx->type);
539 if (!regmap_config) {
540 dev_err(wcd9xxx->dev, "regmap config is not defined\n");
541 return -EINVAL;
542 }
543
544 rc = regmap_reinit_cache(wcd9xxx->regmap, regmap_config);
545 if (rc != 0) {
546 dev_err(wcd9xxx->dev, "%s:Failed to reinit register cache: %d\n",
547 __func__, rc);
548 }
549
550 return rc;
551}
552
553static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx)
554{
555 int ret = 0, i;
556 struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res;
557 regmap_patch_fptr regmap_apply_patch = NULL;
558
559 mutex_init(&wcd9xxx->io_lock);
560 mutex_init(&wcd9xxx->xfer_lock);
561 mutex_init(&wcd9xxx->reset_lock);
562
563 ret = wcd9xxx_bringup(wcd9xxx->dev);
564 if (ret) {
565 ret = -EPROBE_DEFER;
566 goto err_bring_up;
567 }
568
569 wcd9xxx->codec_type = devm_kzalloc(wcd9xxx->dev,
570 sizeof(struct wcd9xxx_codec_type), GFP_KERNEL);
571 if (!wcd9xxx->codec_type) {
572 ret = -ENOMEM;
573 goto err_bring_up;
574 }
575 ret = wcd9xxx_get_codec_info(wcd9xxx->dev);
576 if (ret) {
577 ret = -EPROBE_DEFER;
578 goto fail_cdc_fill;
579 }
580 wcd9xxx->version = wcd9xxx->codec_type->version;
581 if (!wcd9xxx->codec_type->dev || !wcd9xxx->codec_type->size)
582 goto fail_cdc_fill;
583
584 core_res->parent = wcd9xxx;
585 core_res->dev = wcd9xxx->dev;
586 core_res->intr_table = wcd9xxx->codec_type->intr_tbl;
587 core_res->intr_table_size = wcd9xxx->codec_type->intr_tbl_size;
588
589 for (i = 0; i < WCD9XXX_INTR_REG_MAX; i++)
590 wcd9xxx->core_res.intr_reg[i] =
591 wcd9xxx->codec_type->intr_reg[i];
592
593 wcd9xxx_core_res_init(&wcd9xxx->core_res,
594 wcd9xxx->codec_type->num_irqs,
595 wcd9xxx_num_irq_regs(wcd9xxx),
596 wcd9xxx->regmap);
597
598 if (wcd9xxx_core_irq_init(&wcd9xxx->core_res))
599 goto err;
600
601 ret = wcd9xxx_regmap_init_cache(wcd9xxx);
602 if (ret)
603 goto err_irq;
604
605 regmap_apply_patch = wcd9xxx_get_regmap_reg_patch(
606 wcd9xxx->type);
607 if (regmap_apply_patch) {
608 ret = regmap_apply_patch(wcd9xxx->regmap,
609 wcd9xxx->version);
610 if (ret)
611 dev_err(wcd9xxx->dev,
612 "Failed to register patch: %d\n", ret);
613 }
614
615 ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx->codec_type->dev,
616 wcd9xxx->codec_type->size, NULL, 0, NULL);
617 if (ret != 0) {
618 dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
619 goto err_irq;
620 }
621
622 ret = device_init_wakeup(wcd9xxx->dev, true);
623 if (ret) {
624 dev_err(wcd9xxx->dev, "Device wakeup init failed: %d\n", ret);
625 goto err_irq;
626 }
627
628 return ret;
629err_irq:
630 wcd9xxx_irq_exit(&wcd9xxx->core_res);
631fail_cdc_fill:
632 devm_kfree(wcd9xxx->dev, wcd9xxx->codec_type);
633 wcd9xxx->codec_type = NULL;
634err:
635 wcd9xxx_bringdown(wcd9xxx->dev);
636 wcd9xxx_core_res_deinit(&wcd9xxx->core_res);
637err_bring_up:
638 mutex_destroy(&wcd9xxx->io_lock);
639 mutex_destroy(&wcd9xxx->xfer_lock);
640 mutex_destroy(&wcd9xxx->reset_lock);
641 return ret;
642}
643
644static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
645{
646 device_init_wakeup(wcd9xxx->dev, false);
647 wcd9xxx_irq_exit(&wcd9xxx->core_res);
Laxminath Kasam8f7ccc22017-08-28 17:35:04 +0530648 mfd_remove_devices(wcd9xxx->dev);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530649 wcd9xxx_bringdown(wcd9xxx->dev);
650 wcd9xxx_reset_low(wcd9xxx->dev);
651 wcd9xxx_core_res_deinit(&wcd9xxx->core_res);
652 mutex_destroy(&wcd9xxx->io_lock);
653 mutex_destroy(&wcd9xxx->xfer_lock);
654 mutex_destroy(&wcd9xxx->reset_lock);
655 if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
656 slim_remove_device(wcd9xxx->slim_slave);
657}
658
659
660#ifdef CONFIG_DEBUG_FS
661struct wcd9xxx *debugCodec;
662
663static struct dentry *debugfs_wcd9xxx_dent;
664static struct dentry *debugfs_peek;
665static struct dentry *debugfs_poke;
666static struct dentry *debugfs_power_state;
667static struct dentry *debugfs_reg_dump;
668
669static unsigned char read_data;
670
671static int codec_debug_open(struct inode *inode, struct file *file)
672{
673 file->private_data = inode->i_private;
674 return 0;
675}
676
677static int get_parameters(char *buf, long int *param1, int num_of_par)
678{
679 char *token;
680 int base, cnt;
681
682 token = strsep(&buf, " ");
683
684 for (cnt = 0; cnt < num_of_par; cnt++) {
685 if (token != NULL) {
686 if ((token[1] == 'x') || (token[1] == 'X'))
687 base = 16;
688 else
689 base = 10;
690
691 if (kstrtoul(token, base, &param1[cnt]) != 0)
692 return -EINVAL;
693
694 token = strsep(&buf, " ");
695 } else
696 return -EINVAL;
697 }
698 return 0;
699}
700
701static ssize_t wcd9xxx_slimslave_reg_show(char __user *ubuf, size_t count,
702 loff_t *ppos)
703{
704 int i, reg_val, len;
705 ssize_t total = 0;
706 char tmp_buf[25]; /* each line is 12 bytes but 25 for margin of error */
707
708 for (i = (int) *ppos / 12; i <= SLIM_MAX_REG_ADDR; i++) {
709 reg_val = wcd9xxx_interface_reg_read(debugCodec, i);
710 len = snprintf(tmp_buf, sizeof(tmp_buf),
711 "0x%.3x: 0x%.2x\n", i, reg_val);
Aditya Bavanari8aacfcf2019-06-21 15:56:39 +0530712 if (len < 0) {
713 pr_err("%s: fail to fill the buffer\n", __func__);
714 total = -EFAULT;
715 goto copy_err;
716 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530717
718 if ((total + len) >= count - 1)
719 break;
720 if (copy_to_user((ubuf + total), tmp_buf, len)) {
721 pr_err("%s: fail to copy reg dump\n", __func__);
722 total = -EFAULT;
723 goto copy_err;
724 }
725 *ppos += len;
726 total += len;
727 }
728
729copy_err:
730 return total;
731}
732
733static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
734 size_t count, loff_t *ppos)
735{
736 char lbuf[8];
737 char *access_str = file->private_data;
738 ssize_t ret_cnt;
739
740 if (*ppos < 0 || !count)
741 return -EINVAL;
742
743 if (!strcmp(access_str, "slimslave_peek")) {
744 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
745 ret_cnt = simple_read_from_buffer(ubuf, count, ppos, lbuf,
746 strnlen(lbuf, 7));
747 } else if (!strcmp(access_str, "slimslave_reg_dump")) {
748 ret_cnt = wcd9xxx_slimslave_reg_show(ubuf, count, ppos);
749 } else {
750 pr_err("%s: %s not permitted to read\n", __func__, access_str);
751 ret_cnt = -EPERM;
752 }
753
754 return ret_cnt;
755}
756
757static void wcd9xxx_set_reset_pin_state(struct wcd9xxx *wcd9xxx,
758 struct wcd9xxx_pdata *pdata,
759 bool active)
760{
761 if (wcd9xxx->wcd_rst_np) {
762 if (active)
763 msm_cdc_pinctrl_select_active_state(
764 wcd9xxx->wcd_rst_np);
765 else
766 msm_cdc_pinctrl_select_sleep_state(
767 wcd9xxx->wcd_rst_np);
768
769 return;
770 } else if (gpio_is_valid(wcd9xxx->reset_gpio)) {
771 gpio_direction_output(wcd9xxx->reset_gpio,
772 (active == true ? 1 : 0));
773 }
774}
775
776static int codec_debug_process_cdc_power(char *lbuf)
777{
778 long int param;
779 int rc;
780 struct wcd9xxx_pdata *pdata;
781
782 if (wcd9xxx_get_intf_type() != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
783 pr_err("%s: CODEC is not in SLIMBUS mode\n", __func__);
784 rc = -EPERM;
785 goto error_intf;
786 }
787
788 rc = get_parameters(lbuf, &param, 1);
789
790 if (likely(!rc)) {
791 pdata = debugCodec->slim->dev.platform_data;
792 if (param == 0) {
793 wcd9xxx_slim_device_down(debugCodec->slim);
794 msm_cdc_disable_static_supplies(debugCodec->dev,
795 debugCodec->supplies,
796 pdata->regulator,
797 pdata->num_supplies);
798 wcd9xxx_set_reset_pin_state(debugCodec, pdata, false);
799 } else if (param == 1) {
800 msm_cdc_enable_static_supplies(debugCodec->dev,
801 debugCodec->supplies,
802 pdata->regulator,
803 pdata->num_supplies);
804 usleep_range(1000, 2000);
805 wcd9xxx_set_reset_pin_state(debugCodec, pdata, false);
806 usleep_range(1000, 2000);
807 wcd9xxx_set_reset_pin_state(debugCodec, pdata, true);
808 usleep_range(1000, 2000);
809 wcd9xxx_slim_device_up(debugCodec->slim);
810 } else {
811 pr_err("%s: invalid command %ld\n", __func__, param);
812 }
813 }
814
815error_intf:
816 return rc;
817}
818
819static ssize_t codec_debug_write(struct file *filp,
820 const char __user *ubuf, size_t cnt, loff_t *ppos)
821{
822 char *access_str = filp->private_data;
823 char lbuf[32];
824 int rc;
825 long int param[5];
826
827 if (cnt > sizeof(lbuf) - 1)
828 return -EINVAL;
829
830 rc = copy_from_user(lbuf, ubuf, cnt);
831 if (rc)
832 return -EFAULT;
833
834 lbuf[cnt] = '\0';
835
836 if (!strcmp(access_str, "slimslave_poke")) {
837 /* write */
838 rc = get_parameters(lbuf, param, 2);
839 if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
840 (rc == 0))
841 wcd9xxx_interface_reg_write(debugCodec, param[0],
842 param[1]);
843 else
844 rc = -EINVAL;
845 } else if (!strcmp(access_str, "slimslave_peek")) {
846 /* read */
847 rc = get_parameters(lbuf, param, 1);
848 if ((param[0] <= 0x3FF) && (rc == 0))
849 read_data = wcd9xxx_interface_reg_read(debugCodec,
850 param[0]);
851 else
852 rc = -EINVAL;
853 } else if (!strcmp(access_str, "power_state")) {
854 rc = codec_debug_process_cdc_power(lbuf);
855 }
856
857 if (rc == 0)
858 rc = cnt;
859 else
860 pr_err("%s: rc = %d\n", __func__, rc);
861
862 return rc;
863}
864
865static const struct file_operations codec_debug_ops = {
866 .open = codec_debug_open,
867 .write = codec_debug_write,
868 .read = codec_debug_read
869};
870#endif
871
872static struct wcd9xxx_i2c *wcd9xxx_i2c_get_device_info(struct wcd9xxx *wcd9xxx,
873 u16 reg)
874{
875 u16 mask = 0x0f00;
876 int value = 0;
877 struct wcd9xxx_i2c *wcd9xxx_i2c = NULL;
878
879 if (wcd9xxx->type == WCD9335) {
880 wcd9xxx_i2c = &wcd9xxx_modules[0];
881 } else {
882 value = ((reg & mask) >> 8) & 0x000f;
883 switch (value) {
884 case 0:
885 wcd9xxx_i2c = &wcd9xxx_modules[0];
886 break;
887 case 1:
888 wcd9xxx_i2c = &wcd9xxx_modules[1];
889 break;
890 case 2:
891 wcd9xxx_i2c = &wcd9xxx_modules[2];
892 break;
893 case 3:
894 wcd9xxx_i2c = &wcd9xxx_modules[3];
895 break;
896
897 default:
898 break;
899 }
900 }
901 return wcd9xxx_i2c;
902}
903
904static int wcd9xxx_i2c_write_device(struct wcd9xxx *wcd9xxx, u16 reg, u8 *value,
905 u32 bytes)
906{
907
908 struct i2c_msg *msg;
909 int ret = 0;
910 u8 reg_addr = 0;
Meng Wangc7b180e2018-11-13 09:28:48 +0800911 u8 *data = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530912 struct wcd9xxx_i2c *wcd9xxx_i2c;
913
914 wcd9xxx_i2c = wcd9xxx_i2c_get_device_info(wcd9xxx, reg);
915 if (wcd9xxx_i2c == NULL || wcd9xxx_i2c->client == NULL) {
916 pr_err("failed to get device info\n");
917 return -ENODEV;
918 }
Meng Wangc7b180e2018-11-13 09:28:48 +0800919
920 data = kzalloc(bytes + 1, GFP_KERNEL);
921 if (!data)
922 return -ENOMEM;
923
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530924 reg_addr = (u8)reg;
925 msg = &wcd9xxx_i2c->xfer_msg[0];
926 msg->addr = wcd9xxx_i2c->client->addr;
927 msg->len = bytes + 1;
928 msg->flags = 0;
929 data[0] = reg;
930 data[1] = *value;
931 msg->buf = data;
932 ret = i2c_transfer(wcd9xxx_i2c->client->adapter,
933 wcd9xxx_i2c->xfer_msg, 1);
934 /* Try again if the write fails */
935 if (ret != 1) {
936 ret = i2c_transfer(wcd9xxx_i2c->client->adapter,
937 wcd9xxx_i2c->xfer_msg, 1);
938 if (ret != 1) {
939 pr_err("failed to write the device\n");
Meng Wangc7b180e2018-11-13 09:28:48 +0800940 goto fail;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530941 }
942 }
943 pr_debug("write success register = %x val = %x\n", reg, data[1]);
Meng Wangc7b180e2018-11-13 09:28:48 +0800944fail:
945 kfree(data);
946 return ret;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530947}
948
949
950static int wcd9xxx_i2c_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
951 int bytes, unsigned char *dest)
952{
953 struct i2c_msg *msg;
954 int ret = 0;
955 u8 reg_addr = 0;
956 struct wcd9xxx_i2c *wcd9xxx_i2c;
957 u8 i = 0;
958
959 wcd9xxx_i2c = wcd9xxx_i2c_get_device_info(wcd9xxx, reg);
960 if (wcd9xxx_i2c == NULL || wcd9xxx_i2c->client == NULL) {
961 pr_err("failed to get device info\n");
962 return -ENODEV;
963 }
964 for (i = 0; i < bytes; i++) {
965 reg_addr = (u8)reg++;
966 msg = &wcd9xxx_i2c->xfer_msg[0];
967 msg->addr = wcd9xxx_i2c->client->addr;
968 msg->len = 1;
969 msg->flags = 0;
970 msg->buf = &reg_addr;
971
972 msg = &wcd9xxx_i2c->xfer_msg[1];
973 msg->addr = wcd9xxx_i2c->client->addr;
974 msg->len = 1;
975 msg->flags = I2C_M_RD;
976 msg->buf = dest++;
977 ret = i2c_transfer(wcd9xxx_i2c->client->adapter,
978 wcd9xxx_i2c->xfer_msg, 2);
979
980 /* Try again if read fails first time */
981 if (ret != 2) {
982 ret = i2c_transfer(wcd9xxx_i2c->client->adapter,
983 wcd9xxx_i2c->xfer_msg, 2);
984 if (ret != 2) {
985 pr_err("failed to read wcd9xxx register\n");
986 return ret;
987 }
988 }
989 }
990 return 0;
991}
992
993int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
994 int bytes, void *dest, bool interface_reg)
995{
996 return wcd9xxx_i2c_read_device(wcd9xxx, reg, bytes, dest);
997}
998
999int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
1000 int bytes, void *src, bool interface_reg)
1001{
1002 return wcd9xxx_i2c_write_device(wcd9xxx, reg, src, bytes);
1003}
1004
1005static int wcd9xxx_i2c_get_client_index(struct i2c_client *client,
1006 int *wcd9xx_index)
1007{
1008 int ret = 0;
1009
1010 switch (client->addr) {
1011 case WCD9XXX_I2C_TOP_SLAVE_ADDR:
1012 *wcd9xx_index = WCD9XXX_I2C_TOP_LEVEL;
1013 break;
1014 case WCD9XXX_ANALOG_I2C_SLAVE_ADDR:
1015 *wcd9xx_index = WCD9XXX_I2C_ANALOG;
1016 break;
1017 case WCD9XXX_DIGITAL1_I2C_SLAVE_ADDR:
1018 *wcd9xx_index = WCD9XXX_I2C_DIGITAL_1;
1019 break;
1020 case WCD9XXX_DIGITAL2_I2C_SLAVE_ADDR:
1021 *wcd9xx_index = WCD9XXX_I2C_DIGITAL_2;
1022 break;
1023 default:
1024 ret = -EINVAL;
1025 break;
1026 }
1027 return ret;
1028}
1029
1030static int wcd9xxx_i2c_probe(struct i2c_client *client,
1031 const struct i2c_device_id *id)
1032{
1033 struct wcd9xxx *wcd9xxx = NULL;
1034 struct wcd9xxx_pdata *pdata = NULL;
1035 int val = 0;
1036 int ret = 0;
1037 int wcd9xx_index = 0;
1038 struct device *dev;
1039 int intf_type;
1040 const struct of_device_id *of_id;
1041
1042 intf_type = wcd9xxx_get_intf_type();
1043
1044 pr_debug("%s: interface status %d\n", __func__, intf_type);
1045 if (intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
1046 dev_dbg(&client->dev, "%s:Codec is detected in slimbus mode\n",
1047 __func__);
1048 return -ENODEV;
1049 } else if (intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
1050 ret = wcd9xxx_i2c_get_client_index(client, &wcd9xx_index);
1051 if (ret != 0)
1052 dev_err(&client->dev, "%s: I2C set codec I2C\n"
1053 "client failed\n", __func__);
1054 else {
1055 dev_err(&client->dev, "%s:probe for other slaves\n"
1056 "devices of codec I2C slave Addr = %x\n",
1057 __func__, client->addr);
1058 wcd9xxx_modules[wcd9xx_index].client = client;
1059 }
1060 return ret;
1061 } else if (intf_type == WCD9XXX_INTERFACE_TYPE_PROBING) {
1062 dev = &client->dev;
1063 if (client->dev.of_node) {
1064 dev_dbg(&client->dev, "%s:Platform data\n"
1065 "from device tree\n", __func__);
1066 pdata = wcd9xxx_populate_dt_data(&client->dev);
1067 if (!pdata) {
1068 dev_err(&client->dev,
1069 "%s: Fail to obtain pdata from device tree\n",
1070 __func__);
1071 ret = -EINVAL;
1072 goto fail;
1073 }
1074 client->dev.platform_data = pdata;
1075 } else {
1076 dev_dbg(&client->dev, "%s:Platform data from\n"
1077 "board file\n", __func__);
1078 pdata = client->dev.platform_data;
1079 }
1080 wcd9xxx = devm_kzalloc(&client->dev, sizeof(struct wcd9xxx),
1081 GFP_KERNEL);
1082 if (!wcd9xxx) {
1083 ret = -ENOMEM;
1084 goto fail;
1085 }
1086
1087 if (!pdata) {
1088 dev_dbg(&client->dev, "no platform data?\n");
1089 ret = -EINVAL;
1090 goto fail;
1091 }
1092 wcd9xxx->type = WCD9XXX;
1093 if (client->dev.of_node) {
1094 of_id = of_match_device(wcd9xxx_of_match, &client->dev);
1095 if (of_id) {
1096 wcd9xxx->type = *((int *)of_id->data);
1097 dev_info(&client->dev, "%s: codec type is %d\n",
1098 __func__, wcd9xxx->type);
1099 }
1100 } else {
1101 dev_info(&client->dev, "%s: dev.of_node is NULL, default to WCD9XXX\n",
1102 __func__);
1103 wcd9xxx->type = WCD9XXX;
1104 }
1105 wcd9xxx->regmap = wcd9xxx_regmap_init(&client->dev,
1106 &wcd9xxx_i2c_base_regmap_config);
1107 if (IS_ERR(wcd9xxx->regmap)) {
1108 ret = PTR_ERR(wcd9xxx->regmap);
1109 dev_err(&client->dev, "%s: Failed to allocate register map: %d\n",
1110 __func__, ret);
1111 goto err_codec;
1112 }
1113 wcd9xxx->reset_gpio = pdata->reset_gpio;
1114 wcd9xxx->wcd_rst_np = pdata->wcd_rst_np;
1115
1116 if (!wcd9xxx->wcd_rst_np) {
1117 pdata->use_pinctrl = false;
1118 dev_err(&client->dev, "%s: pinctrl not used for rst_n\n",
1119 __func__);
1120 goto err_codec;
1121 }
1122
1123 if (i2c_check_functionality(client->adapter,
1124 I2C_FUNC_I2C) == 0) {
1125 dev_dbg(&client->dev, "can't talk I2C?\n");
1126 ret = -EIO;
1127 goto fail;
1128 }
1129 dev_set_drvdata(&client->dev, wcd9xxx);
1130 wcd9xxx->dev = &client->dev;
1131 wcd9xxx->dev_up = true;
1132 if (client->dev.of_node)
1133 wcd9xxx->mclk_rate = pdata->mclk_rate;
1134
1135 wcd9xxx->num_of_supplies = pdata->num_supplies;
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05301136 ret = msm_cdc_init_supplies_v2(wcd9xxx->dev, &wcd9xxx->supplies,
1137 pdata->regulator,
1138 pdata->num_supplies,
1139 pdata->vote_regulator_on_demand);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301140 if (!wcd9xxx->supplies) {
1141 dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
1142 __func__);
1143 goto err_codec;
1144 }
1145 ret = msm_cdc_enable_static_supplies(wcd9xxx->dev,
1146 wcd9xxx->supplies,
1147 pdata->regulator,
1148 pdata->num_supplies);
1149 if (ret) {
1150 dev_err(wcd9xxx->dev, "%s: wcd static supply enable failed!\n",
1151 __func__);
1152 goto err_codec;
1153 }
1154 /* For WCD9335, it takes about 600us for the Vout_A and
1155 * Vout_D to be ready after BUCK_SIDO is powered up\
1156 * SYS_RST_N shouldn't be pulled high during this time
1157 */
1158 if (wcd9xxx->type == WCD9335)
1159 usleep_range(600, 650);
1160 else
1161 usleep_range(5, 10);
1162
1163 ret = wcd9xxx_reset(wcd9xxx->dev);
1164 if (ret) {
1165 pr_err("%s: Resetting Codec failed\n", __func__);
1166 goto err_supplies;
1167 }
1168
1169 ret = wcd9xxx_i2c_get_client_index(client, &wcd9xx_index);
1170 if (ret != 0) {
1171 pr_err("%s:Set codec I2C client failed\n", __func__);
1172 goto err_supplies;
1173 }
1174
1175 wcd9xxx_modules[wcd9xx_index].client = client;
1176 wcd9xxx->read_dev = wcd9xxx_i2c_read;
1177 wcd9xxx->write_dev = wcd9xxx_i2c_write;
1178 if (!wcd9xxx->dev->of_node)
1179 wcd9xxx_assign_irq(&wcd9xxx->core_res,
1180 pdata->irq, pdata->irq_base);
1181
1182 ret = wcd9xxx_device_init(wcd9xxx);
1183 if (ret) {
1184 pr_err("%s: error, initializing device failed (%d)\n",
1185 __func__, ret);
1186 goto err_device_init;
1187 }
1188
1189 ret = wcd9xxx_i2c_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1,
1190 &val, 0);
1191 if (ret < 0)
1192 pr_err("%s: failed to read the wcd9xxx status (%d)\n",
1193 __func__, ret);
1194 if (val != wcd9xxx->codec_type->i2c_chip_status)
1195 pr_err("%s: unknown chip status 0x%x\n", __func__, val);
1196
1197 wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_I2C);
1198
1199 return ret;
1200 }
1201
1202 pr_err("%s: I2C probe in wrong state\n", __func__);
1203
1204
1205err_device_init:
1206 wcd9xxx_reset_low(wcd9xxx->dev);
1207err_supplies:
1208 msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies,
1209 pdata->regulator,
1210 pdata->num_supplies);
1211 pdata->regulator = NULL;
1212 pdata->num_supplies = 0;
1213err_codec:
1214 devm_kfree(&client->dev, wcd9xxx);
1215 dev_set_drvdata(&client->dev, NULL);
1216fail:
1217 return ret;
1218}
1219
1220static int wcd9xxx_i2c_remove(struct i2c_client *client)
1221{
1222 struct wcd9xxx *wcd9xxx;
1223 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
1224
1225 wcd9xxx = dev_get_drvdata(&client->dev);
1226 msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies,
1227 pdata->regulator,
1228 pdata->num_supplies);
1229 wcd9xxx_device_exit(wcd9xxx);
1230 dev_set_drvdata(&client->dev, NULL);
1231 return 0;
1232}
1233
1234static int wcd9xxx_dt_parse_slim_interface_dev_info(struct device *dev,
1235 struct slim_device *slim_ifd)
1236{
1237 int ret = 0;
1238 struct property *prop;
1239
1240 ret = of_property_read_string(dev->of_node, "qcom,cdc-slim-ifd",
1241 &slim_ifd->name);
1242 if (ret) {
1243 dev_err(dev, "Looking up %s property in node %s failed",
1244 "qcom,cdc-slim-ifd-dev", dev->of_node->full_name);
1245 return -ENODEV;
1246 }
1247 prop = of_find_property(dev->of_node,
1248 "qcom,cdc-slim-ifd-elemental-addr", NULL);
1249 if (!prop) {
1250 dev_err(dev, "Looking up %s property in node %s failed",
1251 "qcom,cdc-slim-ifd-elemental-addr",
1252 dev->of_node->full_name);
1253 return -ENODEV;
1254 } else if (prop->length != 6) {
1255 dev_err(dev, "invalid codec slim ifd addr. addr length = %d\n",
1256 prop->length);
1257 return -ENODEV;
1258 }
1259 memcpy(slim_ifd->e_addr, prop->value, 6);
1260
1261 return 0;
1262}
1263
1264static int wcd9xxx_slim_get_laddr(struct slim_device *sb,
1265 const u8 *e_addr, u8 e_len, u8 *laddr)
1266{
1267 int ret;
1268 const unsigned long timeout = jiffies +
1269 msecs_to_jiffies(SLIMBUS_PRESENT_TIMEOUT);
1270
1271 do {
1272 ret = slim_get_logical_addr(sb, e_addr, e_len, laddr);
1273 if (!ret)
1274 break;
1275 /* Give SLIMBUS time to report present and be ready. */
1276 usleep_range(1000, 1100);
1277 pr_debug_ratelimited("%s: retyring get logical addr\n",
1278 __func__);
1279 } while time_before(jiffies, timeout);
1280
1281 return ret;
1282}
1283
1284static int wcd9xxx_slim_probe(struct slim_device *slim)
1285{
1286 struct wcd9xxx *wcd9xxx;
1287 struct wcd9xxx_pdata *pdata;
1288 const struct slim_device_id *device_id;
1289 int ret = 0;
1290 int intf_type;
1291
Aditya Bavanari9584db32019-06-21 13:03:02 +05301292 if (!slim)
1293 return -EINVAL;
1294
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301295 intf_type = wcd9xxx_get_intf_type();
1296
1297 wcd9xxx = devm_kzalloc(&slim->dev, sizeof(struct wcd9xxx),
1298 GFP_KERNEL);
Aditya Bavanari9584db32019-06-21 13:03:02 +05301299 if (!wcd9xxx)
1300 return -ENOMEM;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301301
1302 if (intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
1303 dev_dbg(&slim->dev, "%s:Codec is detected in I2C mode\n",
1304 __func__);
1305 ret = -ENODEV;
1306 goto err;
1307 }
1308 if (slim->dev.of_node) {
Karthikeyan Mani2c346ab2018-04-24 18:33:21 -07001309 dev_dbg(&slim->dev, "Platform data from device tree\n");
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301310 pdata = wcd9xxx_populate_dt_data(&slim->dev);
1311 if (!pdata) {
1312 dev_err(&slim->dev,
1313 "%s: Fail to obtain pdata from device tree\n",
1314 __func__);
1315 ret = -EINVAL;
1316 goto err;
1317 }
1318
1319 ret = wcd9xxx_dt_parse_slim_interface_dev_info(&slim->dev,
1320 &pdata->slimbus_slave_device);
1321 if (ret) {
1322 dev_err(&slim->dev, "Error, parsing slim interface\n");
1323 devm_kfree(&slim->dev, pdata);
1324 ret = -EINVAL;
1325 goto err;
1326 }
1327 slim->dev.platform_data = pdata;
1328
1329 } else {
1330 dev_info(&slim->dev, "Platform data from board file\n");
1331 pdata = slim->dev.platform_data;
1332 }
1333
1334 if (!pdata) {
1335 dev_err(&slim->dev, "Error, no platform data\n");
1336 ret = -EINVAL;
1337 goto err;
1338 }
1339
1340 if (!slim->ctrl) {
1341 dev_err(&slim->dev, "%s: Error, no SLIMBUS control data\n",
1342 __func__);
1343 ret = -EINVAL;
1344 goto err_codec;
1345 }
Laxminath Kasam38070be2017-08-17 18:21:59 +05301346
1347 if (pdata->has_buck_vsel_gpio)
1348 msm_cdc_pinctrl_select_active_state(pdata->buck_vsel_ctl_np);
1349
Vatsal Bucha8148b992018-09-27 16:20:30 +05301350 if (pdata->has_micb_supply_en_gpio)
1351 msm_cdc_pinctrl_select_active_state(pdata->micb_en_ctl);
1352
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301353 device_id = slim_get_device_id(slim);
1354 if (!device_id) {
1355 dev_err(&slim->dev, "%s: Error, no device id\n", __func__);
1356 ret = -EINVAL;
1357 goto err;
1358 }
1359
1360 wcd9xxx->type = device_id->driver_data;
1361 dev_info(&slim->dev, "%s: probing for wcd type: %d, name: %s\n",
1362 __func__, wcd9xxx->type, device_id->name);
1363
1364 /* wcd9xxx members init */
1365 wcd9xxx->multi_reg_write = wcd9xxx_slim_multi_reg_write;
1366 wcd9xxx->slim = slim;
1367 slim_set_clientdata(slim, wcd9xxx);
1368 wcd9xxx->reset_gpio = pdata->reset_gpio;
1369 wcd9xxx->dev = &slim->dev;
1370 wcd9xxx->mclk_rate = pdata->mclk_rate;
1371 wcd9xxx->dev_up = true;
1372 wcd9xxx->wcd_rst_np = pdata->wcd_rst_np;
1373
1374 wcd9xxx->regmap = wcd9xxx_regmap_init(&slim->dev,
1375 &wcd9xxx_base_regmap_config);
1376 if (IS_ERR(wcd9xxx->regmap)) {
1377 ret = PTR_ERR(wcd9xxx->regmap);
1378 dev_err(&slim->dev, "%s: Failed to allocate register map: %d\n",
1379 __func__, ret);
1380 goto err_codec;
1381 }
1382
1383 if (!wcd9xxx->wcd_rst_np) {
1384 pdata->use_pinctrl = false;
1385 dev_err(&slim->dev, "%s: pinctrl not used for rst_n\n",
1386 __func__);
1387 goto err_codec;
1388 }
1389
1390 wcd9xxx->num_of_supplies = pdata->num_supplies;
Mangesh Kunchamwar7f6fc832019-01-30 16:24:49 +05301391 ret = msm_cdc_init_supplies_v2(&slim->dev, &wcd9xxx->supplies,
1392 pdata->regulator,
1393 pdata->num_supplies,
1394 pdata->vote_regulator_on_demand);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301395 if (!wcd9xxx->supplies) {
1396 dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
1397 __func__);
1398 goto err_codec;
1399 }
1400 ret = msm_cdc_enable_static_supplies(wcd9xxx->dev,
1401 wcd9xxx->supplies,
1402 pdata->regulator,
1403 pdata->num_supplies);
1404 if (ret) {
1405 dev_err(wcd9xxx->dev, "%s: wcd static supply enable failed!\n",
1406 __func__);
1407 goto err_codec;
1408 }
1409
1410 /*
1411 * For WCD9335, it takes about 600us for the Vout_A and
1412 * Vout_D to be ready after BUCK_SIDO is powered up.
1413 * SYS_RST_N shouldn't be pulled high during this time
1414 */
Meng Wangd6107d02018-11-16 13:06:16 +08001415 if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X)
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301416 usleep_range(600, 650);
1417 else
1418 usleep_range(5, 10);
1419
1420 ret = wcd9xxx_reset(&slim->dev);
1421 if (ret) {
1422 dev_err(&slim->dev, "%s: Resetting Codec failed\n", __func__);
1423 goto err_supplies;
1424 }
1425
1426 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
1427 ARRAY_SIZE(wcd9xxx->slim->e_addr),
1428 &wcd9xxx->slim->laddr);
1429 if (ret) {
1430 dev_err(&slim->dev, "%s: failed to get slimbus %s logical address: %d\n",
1431 __func__, wcd9xxx->slim->name, ret);
1432 goto err_reset;
1433 }
1434 wcd9xxx->read_dev = wcd9xxx_slim_read_device;
1435 wcd9xxx->write_dev = wcd9xxx_slim_write_device;
1436 wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
1437 wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
1438 if (!wcd9xxx->dev->of_node)
1439 wcd9xxx_assign_irq(&wcd9xxx->core_res,
1440 pdata->irq, pdata->irq_base);
1441
1442 ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
1443 if (ret) {
1444 dev_err(&slim->dev, "%s: error, adding SLIMBUS device failed\n",
1445 __func__);
1446 goto err_reset;
1447 }
1448
1449 ret = wcd9xxx_slim_get_laddr(wcd9xxx->slim_slave,
1450 wcd9xxx->slim_slave->e_addr,
1451 ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
1452 &wcd9xxx->slim_slave->laddr);
1453 if (ret) {
1454 dev_err(&slim->dev, "%s: failed to get slimbus %s logical address: %d\n",
1455 __func__, wcd9xxx->slim->name, ret);
1456 goto err_slim_add;
1457 }
1458 wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
1459 wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_SLIMBUS);
1460
1461 ret = wcd9xxx_device_init(wcd9xxx);
1462 if (ret) {
1463 dev_err(&slim->dev, "%s: error, initializing device failed (%d)\n",
1464 __func__, ret);
1465 goto err_slim_add;
1466 }
1467#ifdef CONFIG_DEBUG_FS
1468 debugCodec = wcd9xxx;
1469
1470 debugfs_wcd9xxx_dent = debugfs_create_dir
1471 ("wcd9xxx_core", 0);
1472 if (!IS_ERR(debugfs_wcd9xxx_dent)) {
1473 debugfs_peek = debugfs_create_file("slimslave_peek",
1474 S_IFREG | 0444, debugfs_wcd9xxx_dent,
1475 (void *) "slimslave_peek", &codec_debug_ops);
1476
1477 debugfs_poke = debugfs_create_file("slimslave_poke",
1478 S_IFREG | 0444, debugfs_wcd9xxx_dent,
1479 (void *) "slimslave_poke", &codec_debug_ops);
1480
1481 debugfs_power_state = debugfs_create_file("power_state",
1482 S_IFREG | 0444, debugfs_wcd9xxx_dent,
1483 (void *) "power_state", &codec_debug_ops);
1484
1485 debugfs_reg_dump = debugfs_create_file("slimslave_reg_dump",
1486 S_IFREG | 0444, debugfs_wcd9xxx_dent,
1487 (void *) "slimslave_reg_dump", &codec_debug_ops);
1488 }
1489#endif
1490
1491 return ret;
1492
1493err_slim_add:
1494 slim_remove_device(wcd9xxx->slim_slave);
1495err_reset:
1496 wcd9xxx_reset_low(wcd9xxx->dev);
1497err_supplies:
1498 msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies,
1499 pdata->regulator,
1500 pdata->num_supplies);
1501err_codec:
1502 slim_set_clientdata(slim, NULL);
1503err:
1504 devm_kfree(&slim->dev, wcd9xxx);
1505 return ret;
1506}
1507static int wcd9xxx_slim_remove(struct slim_device *pdev)
1508{
1509 struct wcd9xxx *wcd9xxx;
1510 struct wcd9xxx_pdata *pdata = pdev->dev.platform_data;
1511
1512#ifdef CONFIG_DEBUG_FS
1513 debugfs_remove_recursive(debugfs_wcd9xxx_dent);
1514#endif
1515 wcd9xxx = slim_get_devicedata(pdev);
1516 wcd9xxx_deinit_slimslave(wcd9xxx);
1517 slim_remove_device(wcd9xxx->slim_slave);
1518 msm_cdc_release_supplies(wcd9xxx->dev, wcd9xxx->supplies,
1519 pdata->regulator,
1520 pdata->num_supplies);
1521 wcd9xxx_device_exit(wcd9xxx);
1522 slim_set_clientdata(pdev, NULL);
1523 return 0;
1524}
1525
1526static int wcd9xxx_device_up(struct wcd9xxx *wcd9xxx)
1527{
1528 int ret = 0;
1529 struct wcd9xxx_core_resource *wcd9xxx_res = &wcd9xxx->core_res;
1530
1531 dev_info(wcd9xxx->dev, "%s: codec bring up\n", __func__);
1532 wcd9xxx_bringup(wcd9xxx->dev);
1533 ret = wcd9xxx_irq_init(wcd9xxx_res);
1534 if (ret) {
1535 pr_err("%s: wcd9xx_irq_init failed : %d\n", __func__, ret);
1536 } else {
1537 if (wcd9xxx->post_reset)
1538 ret = wcd9xxx->post_reset(wcd9xxx);
1539 }
1540 return ret;
1541}
1542
1543static int wcd9xxx_slim_device_reset(struct slim_device *sldev)
1544{
1545 int ret;
1546 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1547
1548 if (!wcd9xxx) {
1549 pr_err("%s: wcd9xxx is NULL\n", __func__);
1550 return -EINVAL;
1551 }
1552
Banajit Goswamif6bc7132017-10-20 22:29:42 -07001553 dev_info(wcd9xxx->dev, "%s: device reset, dev_up = %d\n",
1554 __func__, wcd9xxx->dev_up);
1555 if (wcd9xxx->dev_up)
1556 return 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301557
1558 mutex_lock(&wcd9xxx->reset_lock);
1559 ret = wcd9xxx_reset(wcd9xxx->dev);
1560 if (ret)
1561 dev_err(wcd9xxx->dev, "%s: Resetting Codec failed\n", __func__);
1562 mutex_unlock(&wcd9xxx->reset_lock);
1563
1564 return ret;
1565}
1566
1567static int wcd9xxx_slim_device_up(struct slim_device *sldev)
1568{
1569 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1570 int ret = 0;
1571
1572 if (!wcd9xxx) {
1573 pr_err("%s: wcd9xxx is NULL\n", __func__);
1574 return -EINVAL;
1575 }
Banajit Goswamif6bc7132017-10-20 22:29:42 -07001576 dev_info(wcd9xxx->dev, "%s: slim device up, dev_up = %d\n",
1577 __func__, wcd9xxx->dev_up);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301578 if (wcd9xxx->dev_up)
1579 return 0;
1580
1581 wcd9xxx->dev_up = true;
1582
1583 mutex_lock(&wcd9xxx->reset_lock);
1584 ret = wcd9xxx_device_up(wcd9xxx);
1585 mutex_unlock(&wcd9xxx->reset_lock);
1586
1587 return ret;
1588}
1589
1590static int wcd9xxx_slim_device_down(struct slim_device *sldev)
1591{
1592 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1593
1594 if (!wcd9xxx) {
1595 pr_err("%s: wcd9xxx is NULL\n", __func__);
1596 return -EINVAL;
1597 }
1598
Banajit Goswamif6bc7132017-10-20 22:29:42 -07001599 dev_info(wcd9xxx->dev, "%s: device down, dev_up = %d\n",
1600 __func__, wcd9xxx->dev_up);
1601 if (!wcd9xxx->dev_up)
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301602 return 0;
Asish Bhattacharya84f7f732017-07-25 16:29:27 +05301603
Banajit Goswamif6bc7132017-10-20 22:29:42 -07001604 wcd9xxx->dev_up = false;
1605
1606 mutex_lock(&wcd9xxx->reset_lock);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301607 if (wcd9xxx->dev_down)
1608 wcd9xxx->dev_down(wcd9xxx);
1609 wcd9xxx_irq_exit(&wcd9xxx->core_res);
1610 wcd9xxx_reset_low(wcd9xxx->dev);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301611 mutex_unlock(&wcd9xxx->reset_lock);
1612
1613 return 0;
1614}
1615
1616static int wcd9xxx_slim_resume(struct slim_device *sldev)
1617{
1618 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1619
1620 return wcd9xxx_core_res_resume(&wcd9xxx->core_res);
1621}
1622
1623static int wcd9xxx_i2c_resume(struct device *dev)
1624{
1625 struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
1626
1627 if (wcd9xxx)
1628 return wcd9xxx_core_res_resume(&wcd9xxx->core_res);
1629 else
1630 return 0;
1631}
1632
1633static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
1634{
1635 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1636
1637 return wcd9xxx_core_res_suspend(&wcd9xxx->core_res, pmesg);
1638}
1639
1640static int wcd9xxx_i2c_suspend(struct device *dev)
1641{
1642 struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
1643 pm_message_t pmesg = {0};
1644
1645 if (wcd9xxx)
1646 return wcd9xxx_core_res_suspend(&wcd9xxx->core_res, pmesg);
1647 else
1648 return 0;
1649}
1650
1651static const struct slim_device_id wcd_slim_device_id[] = {
1652 {"sitar-slim", 0},
1653 {"sitar1p1-slim", 0},
1654 {"tabla-slim", 0},
1655 {"tabla2x-slim", 0},
1656 {"taiko-slim-pgd", 0},
1657 {"tapan-slim-pgd", 0},
1658 {"tomtom-slim-pgd", WCD9330},
1659 {"tasha-slim-pgd", WCD9335},
1660 {"tavil-slim-pgd", WCD934X},
1661 {}
1662};
1663
1664static struct slim_driver wcd_slim_driver = {
1665 .driver = {
1666 .name = "wcd-slim",
1667 .owner = THIS_MODULE,
1668 },
1669 .probe = wcd9xxx_slim_probe,
1670 .remove = wcd9xxx_slim_remove,
1671 .id_table = wcd_slim_device_id,
1672 .resume = wcd9xxx_slim_resume,
1673 .suspend = wcd9xxx_slim_suspend,
1674 .device_up = wcd9xxx_slim_device_up,
1675 .reset_device = wcd9xxx_slim_device_reset,
1676 .device_down = wcd9xxx_slim_device_down,
1677};
1678
1679static struct i2c_device_id wcd9xxx_id_table[] = {
1680 {"wcd9xxx-i2c", WCD9XXX_I2C_TOP_LEVEL},
1681 {"wcd9xxx-i2c", WCD9XXX_I2C_ANALOG},
1682 {"wcd9xxx-i2c", WCD9XXX_I2C_DIGITAL_1},
1683 {"wcd9xxx-i2c", WCD9XXX_I2C_DIGITAL_2},
1684 {}
1685};
1686
1687static struct i2c_device_id tasha_id_table[] = {
1688 {"tasha-i2c-pgd", WCD9XXX_I2C_TOP_LEVEL},
1689 {}
1690};
1691
Karthikeyan Mani57d3b662017-12-11 15:37:06 -08001692static struct i2c_device_id tavil_id_table[] = {
1693 {"tavil-i2c", WCD9XXX_I2C_TOP_LEVEL},
1694 {}
1695};
1696
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301697static struct i2c_device_id tabla_id_table[] = {
1698 {"tabla top level", WCD9XXX_I2C_TOP_LEVEL},
1699 {"tabla analog", WCD9XXX_I2C_ANALOG},
1700 {"tabla digital1", WCD9XXX_I2C_DIGITAL_1},
1701 {"tabla digital2", WCD9XXX_I2C_DIGITAL_2},
1702 {}
1703};
1704MODULE_DEVICE_TABLE(i2c, tabla_id_table);
1705
1706static const struct dev_pm_ops wcd9xxx_i2c_pm_ops = {
1707 .suspend = wcd9xxx_i2c_suspend,
1708 .resume = wcd9xxx_i2c_resume,
1709};
1710
1711static struct i2c_driver tabla_i2c_driver = {
1712 .driver = {
1713 .owner = THIS_MODULE,
1714 .name = "tabla-i2c-core",
1715 .pm = &wcd9xxx_i2c_pm_ops,
1716 },
1717 .id_table = tabla_id_table,
1718 .probe = wcd9xxx_i2c_probe,
1719 .remove = wcd9xxx_i2c_remove,
1720};
1721
1722static struct i2c_driver wcd9xxx_i2c_driver = {
1723 .driver = {
1724 .owner = THIS_MODULE,
1725 .name = "wcd9xxx-i2c-core",
1726 .pm = &wcd9xxx_i2c_pm_ops,
1727 },
1728 .id_table = wcd9xxx_id_table,
1729 .probe = wcd9xxx_i2c_probe,
1730 .remove = wcd9xxx_i2c_remove,
1731};
1732
1733static struct i2c_driver wcd9335_i2c_driver = {
1734 .driver = {
1735 .owner = THIS_MODULE,
1736 .name = "tasha-i2c-core",
1737 .pm = &wcd9xxx_i2c_pm_ops,
1738 },
1739 .id_table = tasha_id_table,
1740 .probe = wcd9xxx_i2c_probe,
1741 .remove = wcd9xxx_i2c_remove,
1742};
1743
Karthikeyan Mani57d3b662017-12-11 15:37:06 -08001744static struct i2c_driver wcd934x_i2c_driver = {
1745 .driver = {
1746 .owner = THIS_MODULE,
1747 .name = "tavil-i2c-core",
1748 .pm = &wcd9xxx_i2c_pm_ops,
1749 },
1750 .id_table = tavil_id_table,
1751 .probe = wcd9xxx_i2c_probe,
1752 .remove = wcd9xxx_i2c_remove,
1753};
1754
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301755int wcd9xxx_init(void)
1756{
1757 int ret[NUM_WCD9XXX_REG_RET] = {0};
1758 int i = 0;
1759
1760 wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_PROBING);
1761
1762 ret[0] = i2c_add_driver(&tabla_i2c_driver);
1763 if (ret[0])
1764 pr_err("%s: Failed to add the tabla2x I2C driver: %d\n",
1765 __func__, ret[0]);
1766
1767 ret[1] = i2c_add_driver(&wcd9xxx_i2c_driver);
1768 if (ret[1])
1769 pr_err("%s: Failed to add the wcd9xxx I2C driver: %d\n",
1770 __func__, ret[1]);
1771
1772 ret[2] = i2c_add_driver(&wcd9335_i2c_driver);
1773 if (ret[2])
1774 pr_err("%s: Failed to add the wcd9335 I2C driver: %d\n",
1775 __func__, ret[2]);
1776
1777 ret[3] = slim_driver_register(&wcd_slim_driver);
1778 if (ret[3])
1779 pr_err("%s: Failed to register wcd SB driver: %d\n",
1780 __func__, ret[3]);
1781
Karthikeyan Mani57d3b662017-12-11 15:37:06 -08001782 ret[4] = i2c_add_driver(&wcd934x_i2c_driver);
1783 if (ret[4])
1784 pr_err("%s: Failed to add the wcd934x I2C driver: %d\n",
1785 __func__, ret[4]);
1786
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301787 for (i = 0; i < NUM_WCD9XXX_REG_RET; i++) {
1788 if (ret[i])
1789 return ret[i];
1790 }
1791
1792 return 0;
1793}
1794
1795void wcd9xxx_exit(void)
1796{
1797 wcd9xxx_set_intf_type(WCD9XXX_INTERFACE_TYPE_PROBING);
1798
1799 i2c_del_driver(&tabla_i2c_driver);
1800 i2c_del_driver(&wcd9xxx_i2c_driver);
1801 i2c_del_driver(&wcd9335_i2c_driver);
Karthikeyan Mani57d3b662017-12-11 15:37:06 -08001802 i2c_del_driver(&wcd934x_i2c_driver);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301803 slim_driver_unregister(&wcd_slim_driver);
1804}
1805
1806MODULE_DESCRIPTION("Codec core driver");
1807MODULE_LICENSE("GPL v2");