summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c')
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c
new file mode 100644
index 0000000000..24362af0c0
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c
@@ -0,0 +1,167 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Module wrapper for AS3543 audio codec, using /dev/afe (afe.ko) of Samsung YP-R0
10 *
11 * Copyright (c) 2011-2013 Lorenzo Miori
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "fcntl.h"
24#include "unistd.h"
25#include "stdio.h"
26#include "string.h"
27#include "sys/ioctl.h"
28#include "stdlib.h"
29
30#include "ascodec.h"
31
32static int afe_dev = -1;
33
34/* Structure used for ioctl module call */
35struct codec_req_struct {
36 unsigned char reg; /* Main register address */
37 unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/
38 unsigned char value; /* To be read if reading a register; to be set if writing to a register */
39} __attribute__((packed));
40
41
42/* Write to a normal register */
43#define IOCTL_REG_WRITE 0x40034101
44/* Write to a PMU register */
45#define IOCTL_SUBREG_WRITE 0x40034103
46/* Read from a normal register */
47#define IOCTL_REG_READ 0x80034102
48/* Read from a PMU register */
49#define IOCTL_SUBREG_READ 0x80034103
50
51/* Open device */
52void ascodec_init(void)
53{
54 afe_dev = open("/dev/afe", O_RDWR);
55}
56
57/* Close device */
58void ascodec_close(void)
59{
60 if (afe_dev >= 0)
61 close(afe_dev);
62}
63
64/* Write register.
65 * Returns >= 0 if success, -1 if fail
66 */
67int ascodec_write(unsigned int reg, unsigned int value)
68{
69 struct codec_req_struct r = { .reg = reg, .value = value };
70 return ioctl(afe_dev, IOCTL_REG_WRITE, &r);
71}
72
73/* Read register.
74 * Returns -1 if fail, otherwise the register's value if success
75 */
76int ascodec_read(unsigned int reg)
77{
78 struct codec_req_struct r = { .reg = reg };
79 int retval = ioctl(afe_dev, IOCTL_REG_READ, &r);
80 if (retval >= 0)
81 return r.value;
82 else
83 return retval;
84}
85
86/* Write PMU register */
87void ascodec_write_pmu(unsigned int index, unsigned int subreg,
88 unsigned int value)
89{
90 struct codec_req_struct r = {.reg = index, .subreg = subreg, .value = value};
91 ioctl(afe_dev, IOCTL_SUBREG_WRITE, &r);
92}
93
94/* Read PMU register */
95int ascodec_read_pmu(unsigned int index, unsigned int subreg)
96{
97 struct codec_req_struct r = { .reg = index, .subreg = subreg, };
98 int retval = ioctl(afe_dev, IOCTL_SUBREG_READ, &r);
99 if (retval >= 0)
100 return r.value;
101 else
102 return retval;
103}
104
105int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
106{
107 int i, val, ret = 0;
108
109 for (i = 0; i < (int)len; i++)
110 {
111 val = ascodec_read(i + index);
112 if (val >= 0) data[i] = val;
113 else ret = -1;
114 }
115
116 return (ret ?: (int)len);
117}
118
119/*
120 * NOTE:
121 * After the conversion to interrupts, ascodec_(lock|unlock) are only used by
122 * adc-as3514.c to protect against other threads corrupting the result by using
123 * the ADC at the same time. this adc_read() doesn't yield but blocks, so
124 * lock/unlock is not needed
125 *
126 * Additionally, concurrent ascodec_?(read|write) calls are instead protected
127 * by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically
128 * safe
129 */
130
131void ascodec_lock(void)
132{
133}
134
135void ascodec_unlock(void)
136{
137}
138
139bool ascodec_chg_status(void)
140{
141 return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS;
142}
143
144bool ascodec_endofch(void)
145{
146 return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH;
147}
148
149void ascodec_monitor_endofch(void)
150{
151 ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH);
152}
153
154
155void ascodec_write_charger(int value)
156{
157 ascodec_write_pmu(AS3543_CHARGER, 1, value);
158}
159
160int ascodec_read_charger(void)
161{
162 return ascodec_read_pmu(AS3543_CHARGER, 1);
163}
164
165void ascodec_wait_adc_finished(void)
166{
167}