blob: dc0f7bf5bdfb1075230a14f7f680a49be9e36124 [file] [log] [blame]
Duy Truong790f06d2013-02-13 16:38:12 -08001/* Copyright (c) 2009, 2011 The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
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
14#include <linux/slab.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/debugfs.h>
18#include <linux/err.h>
19#include <linux/uaccess.h>
20#include <linux/mutex.h>
21
22#include <mach/pmic.h>
23
24#include "smd_rpcrouter.h"
25
26#define TRACE_PMIC 0
27
28#if TRACE_PMIC
29#define PMIC(x...) printk(KERN_INFO "[PMIC] " x)
30#else
31#define PMIC(x...) do {} while (0)
32#endif
33
34
35#define LIB_NULL_PROC 0
36#define LIB_RPC_GLUE_CODE_INFO_REMOTE_PROC 1
37#define LP_MODE_CONTROL_PROC 2
38#define VREG_SET_LEVEL_PROC 3
39#define VREG_PULL_DOWN_SWITCH_PROC 4
40#define SECURE_MPP_CONFIG_DIGITAL_OUTPUT_PROC 5
41#define SECURE_MPP_CONFIG_I_SINK_PROC 6
42#define RTC_START_PROC 7
43#define RTC_STOP_PROC 8
44#define RTC_GET_TIME_PROC 9
45#define RTC_ENABLE_ALARM_PROC 10
46#define RTC_DISABLE_ALARM_PROC 11
47#define RTC_GET_ALARM_TIME_PROC 12
48#define RTC_GET_ALARM_STATUS_PROC 13
49#define RTC_SET_TIME_ADJUST_PROC 14
50#define RTC_GET_TIME_ADJUST_PROC 15
51#define SET_LED_INTENSITY_PROC 16
52#define FLASH_LED_SET_CURRENT_PROC 17
53#define FLASH_LED_SET_MODE_PROC 18
54#define FLASH_LED_SET_POLARITY_PROC 19
55#define SPEAKER_CMD_PROC 20
56#define SET_SPEAKER_GAIN_PROC 21
57#define VIB_MOT_SET_VOLT_PROC 22
58#define VIB_MOT_SET_MODE_PROC 23
59#define VIB_MOT_SET_POLARITY_PROC 24
60#define VID_EN_PROC 25
61#define VID_IS_EN_PROC 26
62#define VID_LOAD_DETECT_EN_PROC 27
63#define MIC_EN_PROC 28
64#define MIC_IS_EN_PROC 29
65#define MIC_SET_VOLT_PROC 30
66#define MIC_GET_VOLT_PROC 31
67#define SPKR_EN_RIGHT_CHAN_PROC 32
68#define SPKR_IS_RIGHT_CHAN_EN_PROC 33
69#define SPKR_EN_LEFT_CHAN_PROC 34
70#define SPKR_IS_LEFT_CHAN_EN_PROC 35
71#define SET_SPKR_CONFIGURATION_PROC 36
72#define GET_SPKR_CONFIGURATION_PROC 37
73#define SPKR_GET_GAIN_PROC 38
74#define SPKR_IS_EN_PROC 39
75#define SPKR_EN_MUTE_PROC 40
76#define SPKR_IS_MUTE_EN_PROC 41
77#define SPKR_SET_DELAY_PROC 42
78#define SPKR_GET_DELAY_PROC 43
79#define SECURE_MPP_CONFIG_DIGITAL_INPUT_PROC 44
80#define SET_SPEAKER_DELAY_PROC 45
81#define SPEAKER_1K6_ZIN_ENABLE_PROC 46
82#define SPKR_SET_MUX_HPF_CORNER_FREQ_PROC 47
83#define SPKR_GET_MUX_HPF_CORNER_FREQ_PROC 48
84#define SPKR_IS_RIGHT_LEFT_CHAN_ADDED_PROC 49
85#define SPKR_EN_STEREO_PROC 50
86#define SPKR_IS_STEREO_EN_PROC 51
87#define SPKR_SELECT_USB_WITH_HPF_20HZ_PROC 52
88#define SPKR_IS_USB_WITH_HPF_20HZ_PROC 53
89#define SPKR_BYPASS_MUX_PROC 54
90#define SPKR_IS_MUX_BYPASSED_PROC 55
91#define SPKR_EN_HPF_PROC 56
92#define SPKR_IS_HPF_EN_PROC 57
93#define SPKR_EN_SINK_CURR_FROM_REF_VOLT_CIR_PROC 58
94#define SPKR_IS_SINK_CURR_FROM_REF_VOLT_CIR_EN_PROC 59
95#define SPKR_ADD_RIGHT_LEFT_CHAN_PROC 60
96#define SPKR_SET_GAIN_PROC 61
97#define SPKR_EN_PROC 62
98#define HSED_SET_PERIOD_PROC 63
99#define HSED_SET_HYSTERESIS_PROC 64
100#define HSED_SET_CURRENT_THRESHOLD_PROC 65
101#define HSED_ENABLE_PROC 66
102#define HIGH_CURRENT_LED_SET_CURRENT_PROC 67
103#define HIGH_CURRENT_LED_SET_POLARITY_PROC 68
104#define HIGH_CURRENT_LED_SET_MODE_PROC 69
105#define LP_FORCE_LPM_CONTROL_PROC 70
106#define LOW_CURRENT_LED_SET_EXT_SIGNAL_PROC 71
107#define LOW_CURRENT_LED_SET_CURRENT_PROC 72
108#define SPKR_SET_VSEL_LDO_PROC 86
109#define HP_SPKR_CTRL_AUX_GAIN_INPUT_PROC 87
110#define HP_SPKR_MSTR_EN_PROC 88
111#define SPKR_SET_BOOST_PROC 89
112#define HP_SPKR_PRM_IN_EN_PROC 90
113#define HP_SPKR_CTRL_PRM_GAIN_INPUT_PROC 91
114#define HP_SPKR_MUTE_EN_PROC 92
115#define SPKR_BYPASS_EN_PROC 93
116#define HP_SPKR_AUX_IN_EN_PROC 94
117#define XO_CORE_FORCE_ENABLE 96
118#define GPIO_SET_CURRENT_SOURCE_PULLS_PROC 97
119#define GPIO_SET_GPIO_DIRECTION_INPUT_PROC 98
120#define GPIO_SET_EXT_PIN_CONFIG_PROC 99
121#define GPIO_SET_GPIO_CONFIG_PROC 100
122#define GPIO_CONFIG_DIGITAL_OUTPUT_PROC 101
123#define GPIO_GET_GPIO_DIRECTION_PROC 102
124#define GPIO_SET_SLEEP_CLK_CONFIG_PROC 103
125#define GPIO_CONFIG_DIGITAL_INPUT_PROC 104
126#define GPIO_SET_OUTPUT_BUFFER_CONFIGURATION_PROC 105
127#define GPIO_SET_PROC 106
128#define GPIO_CONFIG_MODE_SELECTION_PROC 107
129#define GPIO_SET_INVERSION_CONFIGURATION_PROC 108
130#define GPIO_SET_GPIO_DIRECTION_OUTPUT_PROC 109
131#define GPIO_SET_SOURCE_CONFIGURATION_PROC 110
132#define GPIO_GET_PROC 111
133#define GPIO_SET_VOLTAGE_SOURCE_PROC 112
134#define GPIO_SET_OUTPUT_BUFFER_DRIVE_STRENGTH_PROC 113
135
136/* rpc related */
137#define PMIC_RPC_TIMEOUT (5*HZ)
138
139#define PMIC_PDEV_NAME "rs00010001:00000000"
140#define PMIC_RPC_PROG 0x30000061
141#define PMIC_RPC_VER_1_1 0x00010001
142#define PMIC_RPC_VER_2_1 0x00020001
143#define PMIC_RPC_VER_3_1 0x00030001
144#define PMIC_RPC_VER_5_1 0x00050001
145#define PMIC_RPC_VER_6_1 0x00060001
146
147/* error bit flags defined by modem side */
148#define PM_ERR_FLAG__PAR1_OUT_OF_RANGE (0x0001)
149#define PM_ERR_FLAG__PAR2_OUT_OF_RANGE (0x0002)
150#define PM_ERR_FLAG__PAR3_OUT_OF_RANGE (0x0004)
151#define PM_ERR_FLAG__PAR4_OUT_OF_RANGE (0x0008)
152#define PM_ERR_FLAG__PAR5_OUT_OF_RANGE (0x0010)
153
154#define PM_ERR_FLAG__ALL_PARMS_OUT_OF_RANGE (0x001F) /* all 5 previous */
155
156#define PM_ERR_FLAG__SBI_OPT_ERR (0x0080)
157#define PM_ERR_FLAG__FEATURE_NOT_SUPPORTED (0x0100)
158
159#define PMIC_BUFF_SIZE 256
160
161struct pmic_buf {
162 char *start; /* buffer start addr */
163 char *end; /* buffer end addr */
164 int size; /* buffer size */
165 char *data; /* payload begin addr */
166 int len; /* payload len */
167};
168
169static DEFINE_MUTEX(pmic_mtx);
170
171struct pmic_ctrl {
172 int inited;
173 struct pmic_buf tbuf;
174 struct pmic_buf rbuf;
175 struct msm_rpc_endpoint *endpoint;
176};
177
178static struct pmic_ctrl pmic_ctrl = {
179 .inited = -1,
180};
181
182/* Add newer versions at the top of array */
183static const unsigned int rpc_vers[] = {
184 PMIC_RPC_VER_6_1,
185 PMIC_RPC_VER_5_1,
186 PMIC_RPC_VER_3_1,
187 PMIC_RPC_VER_2_1,
188 PMIC_RPC_VER_1_1,
189};
190
191static int pmic_rpc_req_reply(struct pmic_buf *tbuf,
192 struct pmic_buf *rbuf, int proc);
193static int pmic_rpc_set_only(uint data0, uint data1, uint data2,
194 uint data3, int num, int proc);
195static int pmic_rpc_set_struct(int, uint, uint *data, uint size, int proc);
196static int pmic_rpc_set_get(uint setdata, uint *getdata, int size, int proc);
197static int pmic_rpc_get_only(uint *getdata, int size, int proc);
198
199static int pmic_buf_init(void)
200{
201 struct pmic_ctrl *pm = &pmic_ctrl;
202
203 memset(&pmic_ctrl, 0, sizeof(pmic_ctrl));
204
205 pm->tbuf.start = kmalloc(PMIC_BUFF_SIZE, GFP_KERNEL);
206 if (pm->tbuf.start == NULL) {
207 printk(KERN_ERR "%s:%u\n", __func__, __LINE__);
208 return -ENOMEM;
209 }
210
211 pm->tbuf.data = pm->tbuf.start;
212 pm->tbuf.size = PMIC_BUFF_SIZE;
213 pm->tbuf.end = pm->tbuf.start + PMIC_BUFF_SIZE;
214 pm->tbuf.len = 0;
215
216 pm->rbuf.start = kmalloc(PMIC_BUFF_SIZE, GFP_KERNEL);
217 if (pm->rbuf.start == NULL) {
218 kfree(pm->tbuf.start);
219 printk(KERN_ERR "%s:%u\n", __func__, __LINE__);
220 return -ENOMEM;
221 }
222 pm->rbuf.data = pm->rbuf.start;
223 pm->rbuf.size = PMIC_BUFF_SIZE;
224 pm->rbuf.end = pm->rbuf.start + PMIC_BUFF_SIZE;
225 pm->rbuf.len = 0;
226
227 pm->inited = 1;
228
229 return 0;
230}
231
232static inline void pmic_buf_reserve(struct pmic_buf *bp, int len)
233{
234 bp->data += len;
Trilok Soni9c231a12011-07-12 17:33:20 +0530235 bp->len += len;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700236}
237
238static inline void pmic_buf_reset(struct pmic_buf *bp)
239{
240 bp->data = bp->start;
241 bp->len = 0;
242}
243
244static int modem_to_linux_err(uint err)
245{
246 if (err == 0)
247 return 0;
248
249 if (err & PM_ERR_FLAG__ALL_PARMS_OUT_OF_RANGE)
250 return -EINVAL; /* PM_ERR_FLAG__PAR[1..5]_OUT_OF_RANGE */
251
252 if (err & PM_ERR_FLAG__SBI_OPT_ERR)
253 return -EIO;
254
255 if (err & PM_ERR_FLAG__FEATURE_NOT_SUPPORTED)
256 return -ENOSYS;
257
258 return -EPERM;
259}
260
261static int pmic_put_tx_data(struct pmic_buf *tp, uint datav)
262{
263 uint *lp;
264
265 if ((tp->size - tp->len) < sizeof(datav)) {
266 printk(KERN_ERR "%s: OVERFLOW size=%d len=%d\n",
267 __func__, tp->size, tp->len);
268 return -1;
269 }
270
271 lp = (uint *)tp->data;
272 *lp = cpu_to_be32(datav);
273 tp->data += sizeof(datav);
274 tp->len += sizeof(datav);
275
276 return sizeof(datav);
277}
278
279static int pmic_pull_rx_data(struct pmic_buf *rp, uint *datap)
280{
281 uint *lp;
282
283 if (rp->len < sizeof(*datap)) {
284 printk(KERN_ERR "%s: UNDERRUN len=%d\n", __func__, rp->len);
285 return -1;
286 }
287 lp = (uint *)rp->data;
288 *datap = be32_to_cpu(*lp);
289 rp->data += sizeof(*datap);
290 rp->len -= sizeof(*datap);
291
292 return sizeof(*datap);
293}
294
295
296/*
297 *
298 * +-------------------+
299 * | PROC cmd layer |
300 * +-------------------+
301 * | RPC layer |
302 * +-------------------+
303 *
304 * 1) network byte order
305 * 2) RPC request header(40 bytes) and RPC reply header (24 bytes)
306 * 3) each transaction consists of a request and reply
307 * 3) PROC (comamnd) layer has its own sub-protocol defined
308 * 4) sub-protocol can be grouped to follwoing 7 cases:
309 * a) set one argument, no get
310 * b) set two argument, no get
311 * c) set three argument, no get
312 * d) set a struct, no get
313 * e) set a argument followed by a struct, no get
314 * f) set a argument, get a argument
315 * g) no set, get either a argument or a struct
316 */
317
318/**
319 * pmic_rpc_req_reply() - send request and wait for reply
320 * @tbuf: buffer contains arguments
321 * @rbuf: buffer to be filled with arguments at reply
322 * @proc: command/request id
323 *
324 * This function send request to modem and wait until reply received
325 */
326static int pmic_rpc_req_reply(struct pmic_buf *tbuf, struct pmic_buf *rbuf,
327 int proc)
328{
329 struct pmic_ctrl *pm = &pmic_ctrl;
330 int ans, len, i;
331
332
333 if ((pm->endpoint == NULL) || IS_ERR(pm->endpoint)) {
334 for (i = 0; i < ARRAY_SIZE(rpc_vers); i++) {
335 pm->endpoint = msm_rpc_connect_compatible(PMIC_RPC_PROG,
Jay Chokshi9ae8c852011-08-12 17:22:13 -0700336 rpc_vers[i], MSM_RPC_UNINTERRUPTIBLE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700337
338 if (IS_ERR(pm->endpoint)) {
339 ans = PTR_ERR(pm->endpoint);
340 printk(KERN_ERR "%s: init rpc failed! ans = %d"
341 " for 0x%x version, fallback\n",
342 __func__, ans, rpc_vers[i]);
343 } else {
344 printk(KERN_DEBUG "%s: successfully connected"
345 " to 0x%x rpc version\n",
346 __func__, rpc_vers[i]);
347 break;
348 }
349 }
350 }
351
352 if (IS_ERR(pm->endpoint)) {
353 ans = PTR_ERR(pm->endpoint);
354 return ans;
355 }
356
357 /*
358 * data is point to next available space at this moment,
359 * move it back to beginning of request header and increase
360 * the length
361 */
362 tbuf->data = tbuf->start;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700363
364 len = msm_rpc_call_reply(pm->endpoint, proc,
365 tbuf->data, tbuf->len,
366 rbuf->data, rbuf->size,
367 PMIC_RPC_TIMEOUT);
368
369 if (len <= 0) {
370 printk(KERN_ERR "%s: rpc failed! len = %d\n", __func__, len);
371 pm->endpoint = NULL; /* re-connect later ? */
372 return len;
373 }
374
375 rbuf->len = len;
376 /* strip off rpc_reply_hdr */
377 rbuf->data += sizeof(struct rpc_reply_hdr);
378 rbuf->len -= sizeof(struct rpc_reply_hdr);
379
380 return rbuf->len;
381}
382
383/**
384 * pmic_rpc_set_only() - set arguments and no get
385 * @data0: first argumrnt
386 * @data1: second argument
387 * @data2: third argument
388 * @data3: fourth argument
389 * @num: number of argument
390 * @proc: command/request id
391 *
392 * This function covers case a, b, and c
393 */
394static int pmic_rpc_set_only(uint data0, uint data1, uint data2, uint data3,
395 int num, int proc)
396{
397 struct pmic_ctrl *pm = &pmic_ctrl;
398 struct pmic_buf *tp;
399 struct pmic_buf *rp;
400 int stat;
401
402
403 if (mutex_lock_interruptible(&pmic_mtx))
404 return -ERESTARTSYS;
405
406 if (pm->inited <= 0) {
407 stat = pmic_buf_init();
408 if (stat < 0) {
409 mutex_unlock(&pmic_mtx);
410 return stat;
411 }
412 }
413
414 tp = &pm->tbuf;
415 rp = &pm->rbuf;
416
417 pmic_buf_reset(tp);
418 pmic_buf_reserve(tp, sizeof(struct rpc_request_hdr));
419 pmic_buf_reset(rp);
420
421 if (num > 0)
422 pmic_put_tx_data(tp, data0);
423
424 if (num > 1)
425 pmic_put_tx_data(tp, data1);
426
427 if (num > 2)
428 pmic_put_tx_data(tp, data2);
429
430 if (num > 3)
431 pmic_put_tx_data(tp, data3);
432
433 stat = pmic_rpc_req_reply(tp, rp, proc);
434 if (stat < 0) {
435 mutex_unlock(&pmic_mtx);
436 return stat;
437 }
438
439 pmic_pull_rx_data(rp, &stat); /* result from server */
440
441 mutex_unlock(&pmic_mtx);
442
443 return modem_to_linux_err(stat);
444}
445
446/**
447 * pmic_rpc_set_struct() - set the whole struct
448 * @xflag: indicates an extra argument
449 * @xdata: the extra argument
450 * @*data: starting address of struct
451 * @size: size of struct
452 * @proc: command/request id
453 *
454 * This fucntion covers case d and e
455 */
456static int pmic_rpc_set_struct(int xflag, uint xdata, uint *data, uint size,
457 int proc)
458{
459 struct pmic_ctrl *pm = &pmic_ctrl;
460 struct pmic_buf *tp;
461 struct pmic_buf *rp;
462 int i, stat, more_data;
463
464
465 if (mutex_lock_interruptible(&pmic_mtx))
466 return -ERESTARTSYS;
467
468 if (pm->inited <= 0) {
469 stat = pmic_buf_init();
470 if (stat < 0) {
471 mutex_unlock(&pmic_mtx);
472 return stat;
473 }
474 }
475
476 tp = &pm->tbuf;
477 rp = &pm->rbuf;
478
479 pmic_buf_reset(tp);
480 pmic_buf_reserve(tp, sizeof(struct rpc_request_hdr));
481 pmic_buf_reset(rp);
482
483 if (xflag)
484 pmic_put_tx_data(tp, xdata);
485
486 more_data = 1; /* tell server there have more data followed */
487 pmic_put_tx_data(tp, more_data);
488
489 size >>= 2;
490 for (i = 0; i < size; i++) {
491 pmic_put_tx_data(tp, *data);
492 data++;
493 }
494
495 stat = pmic_rpc_req_reply(tp, rp, proc);
496 if (stat < 0) {
497 mutex_unlock(&pmic_mtx);
498 return stat;
499 }
500
501 pmic_pull_rx_data(rp, &stat); /* result from server */
502
503 mutex_unlock(&pmic_mtx);
504
505 return modem_to_linux_err(stat);
506}
507
508/**
509 * pmic_rpc_set_get() - set one argument and get one argument
510 * @setdata: set argument
511 * @*getdata: memory to store argumnet
512 * @size: size of memory
513 * @proc: command/request id
514 *
515 * This function covers case f
516 */
517static int pmic_rpc_set_get(uint setdata, uint *getdata, int size, int proc)
518{
519 struct pmic_ctrl *pm = &pmic_ctrl;
520 struct pmic_buf *tp;
521 struct pmic_buf *rp;
522 unsigned int *lp;
523 int i, stat, more_data;
524
525
526 if (mutex_lock_interruptible(&pmic_mtx))
527 return -ERESTARTSYS;
528
529 if (pm->inited <= 0) {
530 stat = pmic_buf_init();
531 if (stat < 0) {
532 mutex_unlock(&pmic_mtx);
533 return stat;
534 }
535 }
536
537 tp = &pm->tbuf;
538 rp = &pm->rbuf;
539
540 pmic_buf_reset(tp);
541 pmic_buf_reserve(tp, sizeof(struct rpc_request_hdr));
542 pmic_buf_reset(rp);
543
544 pmic_put_tx_data(tp, setdata);
545
546 /*
547 * more_data = TRUE to ask server reply with requested datum
548 * otherwise, server will reply without datum
549 */
550 more_data = (getdata != NULL);
551 pmic_put_tx_data(tp, more_data);
552
553 stat = pmic_rpc_req_reply(tp, rp, proc);
554 if (stat < 0) {
555 mutex_unlock(&pmic_mtx);
556 return stat;
557 }
558
559 pmic_pull_rx_data(rp, &stat); /* result from server */
560 pmic_pull_rx_data(rp, &more_data);
561
562 if (more_data) { /* more data followed */
563 size >>= 2;
564 lp = getdata;
565 for (i = 0; i < size; i++) {
566 if (pmic_pull_rx_data(rp, lp++) < 0)
567 break; /* not supposed to happen */
568 }
569 }
570
571 mutex_unlock(&pmic_mtx);
572
573 return modem_to_linux_err(stat);
574}
575
576/**
577 * pmic_rpc_get_only() - get one or more than one arguments
578 * @*getdata: memory to store arguments
579 * @size: size of mmory
580 * @proc: command/request id
581 *
582 * This function covers case g
583 */
584static int pmic_rpc_get_only(uint *getdata, int size, int proc)
585{
586 struct pmic_ctrl *pm = &pmic_ctrl;
587 struct pmic_buf *tp;
588 struct pmic_buf *rp;
589 unsigned int *lp;
590 int i, stat, more_data;
591
592
593 if (mutex_lock_interruptible(&pmic_mtx))
594 return -ERESTARTSYS;
595
596 if (pm->inited <= 0) {
597 stat = pmic_buf_init();
598 if (stat < 0) {
599 mutex_unlock(&pmic_mtx);
600 return stat;
601 }
602 }
603
604 tp = &pm->tbuf;
605 rp = &pm->rbuf;
606
607 pmic_buf_reset(tp);
608 pmic_buf_reserve(tp, sizeof(struct rpc_request_hdr));
609 pmic_buf_reset(rp);
610
611 /*
612 * more_data = TRUE to ask server reply with requested datum
613 * otherwise, server will reply without datum
614 */
615 more_data = (getdata != NULL);
616 pmic_put_tx_data(tp, more_data);
617
618 stat = pmic_rpc_req_reply(tp, rp, proc);
619 if (stat < 0) {
620 mutex_unlock(&pmic_mtx);
621 return stat;
622 }
623
624 pmic_pull_rx_data(rp, &stat); /* result from server */
625 pmic_pull_rx_data(rp, &more_data);
626
627 if (more_data) { /* more data followed */
628 size >>= 2;
629 lp = getdata;
630 for (i = 0; i < size; i++) {
631 if (pmic_pull_rx_data(rp, lp++) < 0)
632 break; /* not supposed to happen */
633 }
634 }
635
636 mutex_unlock(&pmic_mtx);
637
638 return modem_to_linux_err(stat);
639}
640
641
642int pmic_lp_mode_control(enum switch_cmd cmd, enum vreg_lp_id id)
643{
644 return pmic_rpc_set_only(cmd, id, 0, 0, 2, LP_MODE_CONTROL_PROC);
645}
646EXPORT_SYMBOL(pmic_lp_mode_control);
647
648int pmic_vreg_set_level(enum vreg_id vreg, int level)
649{
650 return pmic_rpc_set_only(vreg, level, 0, 0, 2, VREG_SET_LEVEL_PROC);
651}
652EXPORT_SYMBOL(pmic_vreg_set_level);
653
654int pmic_vreg_pull_down_switch(enum switch_cmd cmd, enum vreg_pdown_id id)
655{
656 return pmic_rpc_set_only(cmd, id, 0, 0, 2, VREG_PULL_DOWN_SWITCH_PROC);
657}
658EXPORT_SYMBOL(pmic_vreg_pull_down_switch);
659
660int pmic_secure_mpp_control_digital_output(enum mpp_which which,
661 enum mpp_dlogic_level level,
662 enum mpp_dlogic_out_ctrl out)
663{
664 return pmic_rpc_set_only(which, level, out, 0, 3,
665 SECURE_MPP_CONFIG_DIGITAL_OUTPUT_PROC);
666}
667EXPORT_SYMBOL(pmic_secure_mpp_control_digital_output);
668
669int pmic_secure_mpp_config_i_sink(enum mpp_which which,
670 enum mpp_i_sink_level level,
671 enum mpp_i_sink_switch onoff)
672{
673 return pmic_rpc_set_only(which, level, onoff, 0, 3,
674 SECURE_MPP_CONFIG_I_SINK_PROC);
675}
676EXPORT_SYMBOL(pmic_secure_mpp_config_i_sink);
677
678int pmic_secure_mpp_config_digital_input(enum mpp_which which,
679 enum mpp_dlogic_level level,
680 enum mpp_dlogic_in_dbus dbus)
681{
682 return pmic_rpc_set_only(which, level, dbus, 0, 3,
683 SECURE_MPP_CONFIG_DIGITAL_INPUT_PROC);
684}
685EXPORT_SYMBOL(pmic_secure_mpp_config_digital_input);
686
687int pmic_rtc_start(struct rtc_time *time)
688{
689 return pmic_rpc_set_struct(0, 0, (uint *)time, sizeof(*time),
690 RTC_START_PROC);
691}
692EXPORT_SYMBOL(pmic_rtc_start);
693
694int pmic_rtc_stop(void)
695{
696 return pmic_rpc_set_only(0, 0, 0, 0, 0, RTC_STOP_PROC);
697}
698EXPORT_SYMBOL(pmic_rtc_stop);
699
700int pmic_rtc_get_time(struct rtc_time *time)
701{
702 return pmic_rpc_get_only((uint *)time, sizeof(*time),
703 RTC_GET_TIME_PROC);
704}
705EXPORT_SYMBOL(pmic_rtc_get_time);
706
707int pmic_rtc_enable_alarm(enum rtc_alarm alarm,
708 struct rtc_time *time)
709{
710 return pmic_rpc_set_struct(1, alarm, (uint *)time, sizeof(*time),
711 RTC_ENABLE_ALARM_PROC);
712}
713EXPORT_SYMBOL(pmic_rtc_enable_alarm);
714
715int pmic_rtc_disable_alarm(enum rtc_alarm alarm)
716{
717 return pmic_rpc_set_only(alarm, 0, 0, 0, 1, RTC_DISABLE_ALARM_PROC);
718}
719EXPORT_SYMBOL(pmic_rtc_disable_alarm);
720
721int pmic_rtc_get_alarm_time(enum rtc_alarm alarm,
722 struct rtc_time *time)
723{
724 return pmic_rpc_set_get(alarm, (uint *)time, sizeof(*time),
725 RTC_GET_ALARM_TIME_PROC);
726}
727EXPORT_SYMBOL(pmic_rtc_get_alarm_time);
728
729int pmic_rtc_get_alarm_status(uint *status)
730{
731 return pmic_rpc_get_only(status, sizeof(*status),
732 RTC_GET_ALARM_STATUS_PROC);
733}
734EXPORT_SYMBOL(pmic_rtc_get_alarm_status);
735
736int pmic_rtc_set_time_adjust(uint adjust)
737{
738 return pmic_rpc_set_only(adjust, 0, 0, 0, 1,
739 RTC_SET_TIME_ADJUST_PROC);
740}
741EXPORT_SYMBOL(pmic_rtc_set_time_adjust);
742
743int pmic_rtc_get_time_adjust(uint *adjust)
744{
745 return pmic_rpc_get_only(adjust, sizeof(*adjust),
746 RTC_GET_TIME_ADJUST_PROC);
747}
748EXPORT_SYMBOL(pmic_rtc_get_time_adjust);
749
750/*
751 * generic speaker
752 */
753int pmic_speaker_cmd(const enum spkr_cmd cmd)
754{
755 return pmic_rpc_set_only(cmd, 0, 0, 0, 1, SPEAKER_CMD_PROC);
756}
757EXPORT_SYMBOL(pmic_speaker_cmd);
758
759int pmic_set_spkr_configuration(struct spkr_config_mode *cfg)
760{
761 return pmic_rpc_set_struct(0, 0, (uint *)cfg, sizeof(*cfg),
762 SET_SPKR_CONFIGURATION_PROC);
763}
764EXPORT_SYMBOL(pmic_set_spkr_configuration);
765
766int pmic_get_spkr_configuration(struct spkr_config_mode *cfg)
767{
768 return pmic_rpc_get_only((uint *)cfg, sizeof(*cfg),
769 GET_SPKR_CONFIGURATION_PROC);
770}
771EXPORT_SYMBOL(pmic_get_spkr_configuration);
772
773int pmic_spkr_en_right_chan(uint enable)
774{
775 return pmic_rpc_set_only(enable, 0, 0, 0, 1, SPKR_EN_RIGHT_CHAN_PROC);
776}
777EXPORT_SYMBOL(pmic_spkr_en_right_chan);
778
779int pmic_spkr_is_right_chan_en(uint *enabled)
780{
781 return pmic_rpc_get_only(enabled, sizeof(*enabled),
782 SPKR_IS_RIGHT_CHAN_EN_PROC);
783}
784EXPORT_SYMBOL(pmic_spkr_is_right_chan_en);
785
786int pmic_spkr_en_left_chan(uint enable)
787{
788 return pmic_rpc_set_only(enable, 0, 0, 0, 1, SPKR_EN_LEFT_CHAN_PROC);
789}
790EXPORT_SYMBOL(pmic_spkr_en_left_chan);
791
792int pmic_spkr_is_left_chan_en(uint *enabled)
793{
794 return pmic_rpc_get_only(enabled, sizeof(*enabled),
795 SPKR_IS_LEFT_CHAN_EN_PROC);
796}
797EXPORT_SYMBOL(pmic_spkr_is_left_chan_en);
798
799int pmic_set_speaker_gain(enum spkr_gain gain)
800{
801 return pmic_rpc_set_only(gain, 0, 0, 0, 1, SET_SPEAKER_GAIN_PROC);
802}
803EXPORT_SYMBOL(pmic_set_speaker_gain);
804
805int pmic_set_speaker_delay(enum spkr_dly delay)
806{
807 return pmic_rpc_set_only(delay, 0, 0, 0, 1, SET_SPEAKER_DELAY_PROC);
808}
809EXPORT_SYMBOL(pmic_set_speaker_delay);
810
811int pmic_speaker_1k6_zin_enable(uint enable)
812{
813 return pmic_rpc_set_only(enable, 0, 0, 0, 1,
814 SPEAKER_1K6_ZIN_ENABLE_PROC);
815}
816EXPORT_SYMBOL(pmic_speaker_1k6_zin_enable);
817
818int pmic_spkr_set_mux_hpf_corner_freq(enum spkr_hpf_corner_freq freq)
819{
820 return pmic_rpc_set_only(freq, 0, 0, 0, 1,
821 SPKR_SET_MUX_HPF_CORNER_FREQ_PROC);
822}
823EXPORT_SYMBOL(pmic_spkr_set_mux_hpf_corner_freq);
824
825int pmic_spkr_get_mux_hpf_corner_freq(enum spkr_hpf_corner_freq *freq)
826{
827 return pmic_rpc_get_only(freq, sizeof(*freq),
828 SPKR_GET_MUX_HPF_CORNER_FREQ_PROC);
829}
830EXPORT_SYMBOL(pmic_spkr_get_mux_hpf_corner_freq);
831
832int pmic_spkr_select_usb_with_hpf_20hz(uint enable)
833{
834 return pmic_rpc_set_only(enable, 0, 0, 0, 1,
835 SPKR_SELECT_USB_WITH_HPF_20HZ_PROC);
836}
837EXPORT_SYMBOL(pmic_spkr_select_usb_with_hpf_20hz);
838
839int pmic_spkr_is_usb_with_hpf_20hz(uint *enabled)
840{
841 return pmic_rpc_get_only(enabled, sizeof(*enabled),
842 SPKR_IS_USB_WITH_HPF_20HZ_PROC);
843}
844EXPORT_SYMBOL(pmic_spkr_is_usb_with_hpf_20hz);
845
846int pmic_spkr_bypass_mux(uint enable)
847{
848 return pmic_rpc_set_only(enable, 0, 0, 0, 1, SPKR_BYPASS_MUX_PROC);
849}
850EXPORT_SYMBOL(pmic_spkr_bypass_mux);
851
852int pmic_spkr_is_mux_bypassed(uint *enabled)
853{
854 return pmic_rpc_get_only(enabled, sizeof(*enabled),
855 SPKR_IS_MUX_BYPASSED_PROC);
856}
857EXPORT_SYMBOL(pmic_spkr_is_mux_bypassed);
858
859int pmic_spkr_en_hpf(uint enable)
860{
861 return pmic_rpc_set_only(enable, 0, 0, 0, 1, SPKR_EN_HPF_PROC);
862}
863EXPORT_SYMBOL(pmic_spkr_en_hpf);
864
865int pmic_spkr_is_hpf_en(uint *enabled)
866{
867 return pmic_rpc_get_only(enabled, sizeof(*enabled),
868 SPKR_IS_HPF_EN_PROC);
869}
870EXPORT_SYMBOL(pmic_spkr_is_hpf_en);
871
872int pmic_spkr_en_sink_curr_from_ref_volt_cir(uint enable)
873{
874 return pmic_rpc_set_only(enable, 0, 0, 0, 1,
875 SPKR_EN_SINK_CURR_FROM_REF_VOLT_CIR_PROC);
876}
877EXPORT_SYMBOL(pmic_spkr_en_sink_curr_from_ref_volt_cir);
878
879int pmic_spkr_is_sink_curr_from_ref_volt_cir_en(uint *enabled)
880{
881 return pmic_rpc_get_only(enabled, sizeof(*enabled),
882 SPKR_IS_SINK_CURR_FROM_REF_VOLT_CIR_EN_PROC);
883}
884EXPORT_SYMBOL(pmic_spkr_is_sink_curr_from_ref_volt_cir_en);
885
886/*
887 * speaker indexed by left_right
888 */
889int pmic_spkr_en(enum spkr_left_right left_right, uint enable)
890{
891 return pmic_rpc_set_only(left_right, enable, 0, 0, 2, SPKR_EN_PROC);
892}
893EXPORT_SYMBOL(pmic_spkr_en);
894
895int pmic_spkr_is_en(enum spkr_left_right left_right, uint *enabled)
896{
897 return pmic_rpc_set_get(left_right, enabled, sizeof(*enabled),
898 SPKR_IS_EN_PROC);
899}
900EXPORT_SYMBOL(pmic_spkr_is_en);
901
902int pmic_spkr_set_gain(enum spkr_left_right left_right, enum spkr_gain gain)
903{
904 return pmic_rpc_set_only(left_right, gain, 0, 0, 2, SPKR_SET_GAIN_PROC);
905}
906EXPORT_SYMBOL(pmic_spkr_set_gain);
907
908int pmic_spkr_get_gain(enum spkr_left_right left_right, enum spkr_gain *gain)
909{
910 return pmic_rpc_set_get(left_right, gain, sizeof(*gain),
911 SPKR_GET_GAIN_PROC);
912}
913EXPORT_SYMBOL(pmic_spkr_get_gain);
914
915int pmic_spkr_set_delay(enum spkr_left_right left_right, enum spkr_dly delay)
916{
917 return pmic_rpc_set_only(left_right, delay, 0, 0, 2,
918 SPKR_SET_DELAY_PROC);
919}
920EXPORT_SYMBOL(pmic_spkr_set_delay);
921
922int pmic_spkr_get_delay(enum spkr_left_right left_right, enum spkr_dly *delay)
923{
924 return pmic_rpc_set_get(left_right, delay, sizeof(*delay),
925 SPKR_GET_DELAY_PROC);
926}
927EXPORT_SYMBOL(pmic_spkr_get_delay);
928
929int pmic_spkr_en_mute(enum spkr_left_right left_right, uint enabled)
930{
931 return pmic_rpc_set_only(left_right, enabled, 0, 0, 2,
932 SPKR_EN_MUTE_PROC);
933}
934EXPORT_SYMBOL(pmic_spkr_en_mute);
935
936int pmic_spkr_is_mute_en(enum spkr_left_right left_right, uint *enabled)
937{
938 return pmic_rpc_set_get(left_right, enabled, sizeof(*enabled),
939 SPKR_IS_MUTE_EN_PROC);
940}
941EXPORT_SYMBOL(pmic_spkr_is_mute_en);
942
943int pmic_spkr_set_vsel_ldo(enum spkr_left_right left_right,
944 enum spkr_ldo_v_sel vlt_cntrl)
945{
946 return pmic_rpc_set_only(left_right, vlt_cntrl, 0, 0, 2,
947 SPKR_SET_VSEL_LDO_PROC);
948}
949EXPORT_SYMBOL(pmic_spkr_set_vsel_ldo);
950
951int pmic_spkr_set_boost(enum spkr_left_right left_right, uint enable)
952{
953 return pmic_rpc_set_only(left_right, enable, 0, 0, 2,
954 SPKR_SET_BOOST_PROC);
955}
956EXPORT_SYMBOL(pmic_spkr_set_boost);
957
958int pmic_spkr_bypass_en(enum spkr_left_right left_right, uint enable)
959{
960 return pmic_rpc_set_only(left_right, enable, 0, 0, 2,
961 SPKR_BYPASS_EN_PROC);
962}
963EXPORT_SYMBOL(pmic_spkr_bypass_en);
964
965/*
966 * mic
967 */
968int pmic_mic_en(uint enable)
969{
970 return pmic_rpc_set_only(enable, 0, 0, 0, 1, MIC_EN_PROC);
971}
972EXPORT_SYMBOL(pmic_mic_en);
973
974int pmic_mic_is_en(uint *enabled)
975{
976 return pmic_rpc_get_only(enabled, sizeof(*enabled), MIC_IS_EN_PROC);
977}
978EXPORT_SYMBOL(pmic_mic_is_en);
979
980int pmic_mic_set_volt(enum mic_volt vol)
981{
982 return pmic_rpc_set_only(vol, 0, 0, 0, 1, MIC_SET_VOLT_PROC);
983}
984EXPORT_SYMBOL(pmic_mic_set_volt);
985
986int pmic_mic_get_volt(enum mic_volt *voltage)
987{
988 return pmic_rpc_get_only(voltage, sizeof(*voltage), MIC_GET_VOLT_PROC);
989}
990EXPORT_SYMBOL(pmic_mic_get_volt);
991
992int pmic_vib_mot_set_volt(uint vol)
993{
994 return pmic_rpc_set_only(vol, 0, 0, 0, 1, VIB_MOT_SET_VOLT_PROC);
995}
996EXPORT_SYMBOL(pmic_vib_mot_set_volt);
997
998int pmic_vib_mot_set_mode(enum pm_vib_mot_mode mode)
999{
1000 return pmic_rpc_set_only(mode, 0, 0, 0, 1, VIB_MOT_SET_MODE_PROC);
1001}
1002EXPORT_SYMBOL(pmic_vib_mot_set_mode);
1003
1004int pmic_vib_mot_set_polarity(enum pm_vib_mot_pol pol)
1005{
1006 return pmic_rpc_set_only(pol, 0, 0, 0, 1, VIB_MOT_SET_POLARITY_PROC);
1007}
1008EXPORT_SYMBOL(pmic_vib_mot_set_polarity);
1009
1010int pmic_vid_en(uint enable)
1011{
1012 return pmic_rpc_set_only(enable, 0, 0, 0, 1, VID_EN_PROC);
1013}
1014EXPORT_SYMBOL(pmic_vid_en);
1015
1016int pmic_vid_is_en(uint *enabled)
1017{
1018 return pmic_rpc_get_only(enabled, sizeof(*enabled), VID_IS_EN_PROC);
1019}
1020EXPORT_SYMBOL(pmic_vid_is_en);
1021
1022int pmic_vid_load_detect_en(uint enable)
1023{
1024 return pmic_rpc_set_only(enable, 0, 0, 0, 1, VID_LOAD_DETECT_EN_PROC);
1025}
1026EXPORT_SYMBOL(pmic_vid_load_detect_en);
1027
1028int pmic_set_led_intensity(enum ledtype type, int level)
1029{
1030 return pmic_rpc_set_only(type, level, 0, 0, 2, SET_LED_INTENSITY_PROC);
1031}
1032EXPORT_SYMBOL(pmic_set_led_intensity);
1033
1034int pmic_flash_led_set_current(const uint16_t milliamps)
1035{
1036 return pmic_rpc_set_only(milliamps, 0, 0, 0, 1,
1037 FLASH_LED_SET_CURRENT_PROC);
1038}
1039EXPORT_SYMBOL(pmic_flash_led_set_current);
1040
1041int pmic_flash_led_set_mode(enum flash_led_mode mode)
1042{
1043 return pmic_rpc_set_only((int)mode, 0, 0, 0, 1,
1044 FLASH_LED_SET_MODE_PROC);
1045}
1046EXPORT_SYMBOL(pmic_flash_led_set_mode);
1047
1048int pmic_flash_led_set_polarity(enum flash_led_pol pol)
1049{
1050 return pmic_rpc_set_only((int)pol, 0, 0, 0, 1,
1051 FLASH_LED_SET_POLARITY_PROC);
1052}
1053EXPORT_SYMBOL(pmic_flash_led_set_polarity);
1054
1055int pmic_spkr_add_right_left_chan(uint enable)
1056{
1057 return pmic_rpc_set_only(enable, 0, 0, 0, 1,
1058 SPKR_ADD_RIGHT_LEFT_CHAN_PROC);
1059}
1060EXPORT_SYMBOL(pmic_spkr_add_right_left_chan);
1061
1062int pmic_spkr_is_right_left_chan_added(uint *enabled)
1063{
1064 return pmic_rpc_get_only(enabled, sizeof(*enabled),
1065 SPKR_IS_RIGHT_LEFT_CHAN_ADDED_PROC);
1066}
1067EXPORT_SYMBOL(pmic_spkr_is_right_left_chan_added);
1068
1069int pmic_spkr_en_stereo(uint enable)
1070{
1071 return pmic_rpc_set_only(enable, 0, 0, 0, 1, SPKR_EN_STEREO_PROC);
1072}
1073EXPORT_SYMBOL(pmic_spkr_en_stereo);
1074
1075int pmic_spkr_is_stereo_en(uint *enabled)
1076{
1077 return pmic_rpc_get_only(enabled, sizeof(*enabled),
1078 SPKR_IS_STEREO_EN_PROC);
1079}
1080EXPORT_SYMBOL(pmic_spkr_is_stereo_en);
1081
1082int pmic_hsed_set_period(
1083 enum hsed_controller controller,
1084 enum hsed_period_pre_div period_pre_div,
1085 enum hsed_period_time period_time
1086)
1087{
1088 return pmic_rpc_set_only(controller, period_pre_div, period_time, 0,
1089 3,
1090 HSED_SET_PERIOD_PROC);
1091}
1092EXPORT_SYMBOL(pmic_hsed_set_period);
1093
1094int pmic_hsed_set_hysteresis(
1095 enum hsed_controller controller,
1096 enum hsed_hyst_pre_div hyst_pre_div,
1097 enum hsed_hyst_time hyst_time
1098)
1099{
1100 return pmic_rpc_set_only(controller, hyst_pre_div, hyst_time, 0,
1101 3,
1102 HSED_SET_HYSTERESIS_PROC);
1103}
1104EXPORT_SYMBOL(pmic_hsed_set_hysteresis);
1105
1106int pmic_hsed_set_current_threshold(
1107 enum hsed_controller controller,
1108 enum hsed_switch switch_hsed,
1109 uint32_t current_threshold
1110)
1111{
1112 return pmic_rpc_set_only(controller, switch_hsed, current_threshold, 0,
1113 3,
1114 HSED_SET_CURRENT_THRESHOLD_PROC);
1115}
1116EXPORT_SYMBOL(pmic_hsed_set_current_threshold);
1117
1118int pmic_hsed_enable(
1119 enum hsed_controller controller,
1120 enum hsed_enable enable_hsed
1121)
1122{
1123 return pmic_rpc_set_only(controller, enable_hsed, 0, 0,
1124 2,
1125 HSED_ENABLE_PROC);
1126}
1127EXPORT_SYMBOL(pmic_hsed_enable);
1128
1129int pmic_high_current_led_set_current(enum high_current_led led,
1130 uint16_t milliamps)
1131{
1132 return pmic_rpc_set_only(led, milliamps, 0, 0,
1133 2,
1134 HIGH_CURRENT_LED_SET_CURRENT_PROC);
1135}
1136EXPORT_SYMBOL(pmic_high_current_led_set_current);
1137
1138int pmic_high_current_led_set_polarity(enum high_current_led led,
1139 enum flash_led_pol polarity)
1140{
1141 return pmic_rpc_set_only(led, polarity, 0, 0,
1142 2,
1143 HIGH_CURRENT_LED_SET_POLARITY_PROC);
1144}
1145EXPORT_SYMBOL(pmic_high_current_led_set_polarity);
1146
1147int pmic_high_current_led_set_mode(enum high_current_led led,
1148 enum flash_led_mode mode)
1149{
1150 return pmic_rpc_set_only(led, mode, 0, 0,
1151 2,
1152 HIGH_CURRENT_LED_SET_MODE_PROC);
1153}
1154EXPORT_SYMBOL(pmic_high_current_led_set_mode);
1155
1156int pmic_lp_force_lpm_control(enum switch_cmd cmd,
1157 enum vreg_lpm_id vreg)
1158{
1159 return pmic_rpc_set_only(cmd, vreg, 0, 0,
1160 2,
1161 LP_FORCE_LPM_CONTROL_PROC);
1162}
1163EXPORT_SYMBOL(pmic_lp_force_lpm_control);
1164
1165int pmic_low_current_led_set_ext_signal(enum low_current_led led,
1166 enum ext_signal sig)
1167{
1168 return pmic_rpc_set_only(led, sig, 0, 0,
1169 2,
1170 LOW_CURRENT_LED_SET_EXT_SIGNAL_PROC);
1171}
1172EXPORT_SYMBOL(pmic_low_current_led_set_ext_signal);
1173
1174int pmic_low_current_led_set_current(enum low_current_led led,
1175 uint16_t milliamps)
1176{
1177 return pmic_rpc_set_only(led, milliamps, 0, 0,
1178 2,
1179 LOW_CURRENT_LED_SET_CURRENT_PROC);
1180}
1181EXPORT_SYMBOL(pmic_low_current_led_set_current);
1182
1183/*
1184 * Head phone speaker
1185 */
1186int pmic_hp_spkr_mstr_en(enum hp_spkr_left_right left_right, uint enable)
1187{
1188 return pmic_rpc_set_only(left_right, enable, 0, 0, 2,
1189 HP_SPKR_MSTR_EN_PROC);
1190}
1191EXPORT_SYMBOL(pmic_hp_spkr_mstr_en);
1192
1193int pmic_hp_spkr_mute_en(enum hp_spkr_left_right left_right, uint enable)
1194{
1195 return pmic_rpc_set_only(left_right, enable, 0, 0, 2,
1196 HP_SPKR_MUTE_EN_PROC);
1197}
1198EXPORT_SYMBOL(pmic_hp_spkr_mute_en);
1199
1200int pmic_hp_spkr_prm_in_en(enum hp_spkr_left_right left_right, uint enable)
1201{
1202 return pmic_rpc_set_only(left_right, enable, 0, 0, 2,
1203 HP_SPKR_PRM_IN_EN_PROC);
1204}
1205EXPORT_SYMBOL(pmic_hp_spkr_prm_in_en);
1206
1207int pmic_hp_spkr_aux_in_en(enum hp_spkr_left_right left_right, uint enable)
1208{
1209 return pmic_rpc_set_only(left_right, enable, 0, 0, 2,
1210 HP_SPKR_AUX_IN_EN_PROC);
1211}
1212EXPORT_SYMBOL(pmic_hp_spkr_aux_in_en);
1213
1214int pmic_hp_spkr_ctrl_prm_gain_input(enum hp_spkr_left_right left_right,
1215 uint prm_gain_ctl)
1216{
1217 return pmic_rpc_set_only(left_right, prm_gain_ctl, 0, 0, 2,
1218 HP_SPKR_CTRL_PRM_GAIN_INPUT_PROC);
1219}
1220EXPORT_SYMBOL(pmic_hp_spkr_ctrl_prm_gain_input);
1221
1222int pmic_hp_spkr_ctrl_aux_gain_input(enum hp_spkr_left_right left_right,
1223 uint aux_gain_ctl)
1224{
1225 return pmic_rpc_set_only(left_right, aux_gain_ctl, 0, 0, 2,
1226 HP_SPKR_CTRL_AUX_GAIN_INPUT_PROC);
1227}
1228EXPORT_SYMBOL(pmic_hp_spkr_ctrl_aux_gain_input);
1229
1230int pmic_xo_core_force_enable(uint enable)
1231{
1232 return pmic_rpc_set_only(enable, 0, 0, 0, 1, XO_CORE_FORCE_ENABLE);
1233}
1234EXPORT_SYMBOL(pmic_xo_core_force_enable);
1235
1236int pmic_gpio_direction_input(unsigned gpio)
1237{
1238 return pmic_rpc_set_only(gpio, 0, 0, 0, 1,
1239 GPIO_SET_GPIO_DIRECTION_INPUT_PROC);
1240}
1241EXPORT_SYMBOL(pmic_gpio_direction_input);
1242
1243int pmic_gpio_direction_output(unsigned gpio)
1244{
1245 return pmic_rpc_set_only(gpio, 0, 0, 0, 1,
1246 GPIO_SET_GPIO_DIRECTION_OUTPUT_PROC);
1247}
1248EXPORT_SYMBOL(pmic_gpio_direction_output);
1249
1250int pmic_gpio_set_value(unsigned gpio, int value)
1251{
1252 return pmic_rpc_set_only(gpio, value, 0, 0, 2, GPIO_SET_PROC);
1253}
1254EXPORT_SYMBOL(pmic_gpio_set_value);
1255
1256int pmic_gpio_get_value(unsigned gpio)
1257{
1258 uint value;
1259 int ret;
1260
1261 ret = pmic_rpc_set_get(gpio, &value, sizeof(value), GPIO_GET_PROC);
1262 if (ret < 0)
1263 return ret;
1264 return value ? 1 : 0;
1265}
1266EXPORT_SYMBOL(pmic_gpio_get_value);
1267
1268int pmic_gpio_get_direction(unsigned gpio)
1269{
1270 enum pmic_direction_mode dir;
1271 int ret;
1272
1273 ret = pmic_rpc_set_get(gpio, &dir, sizeof(dir),
1274 GPIO_GET_GPIO_DIRECTION_PROC);
1275 if (ret < 0)
1276 return ret;
1277 return dir;
1278}
1279EXPORT_SYMBOL(pmic_gpio_get_direction);
1280
1281int pmic_gpio_config(struct pm8xxx_gpio_rpc_cfg *param)
1282{
1283 return pmic_rpc_set_struct(0, 0, (uint *)param, sizeof(*param),
1284 GPIO_SET_GPIO_CONFIG_PROC);
1285}
1286EXPORT_SYMBOL(pmic_gpio_config);