1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * $Id: ascodec-target.h 26116 2010-05-17 20:53:25Z funman $
10 * Module wrapper for AS3543 audio codec, using /dev/afe (afe.ko) of Samsung YP-R0
12 * Copyright (c) 2011 Lorenzo Miori
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
28 #include "sys/ioctl.h"
31 #include "ascodec-target.h"
35 /* Write to a normal register */
36 #define IOCTL_REG_WRITE 0x40034101
37 /* Write to a PMU register */
38 #define IOCTL_SUBREG_WRITE 0x40034103
39 /* Read from a normal register */
40 #define IOCTL_REG_READ 0x80034102
41 /* Read from a PMU register */
42 #define IOCTL_SUBREG_READ 0x80034103
44 static struct mutex as_mtx
;
46 int ascodec_init(void) {
48 afe_dev
= open("/dev/afe", O_RDWR
);
56 void ascodec_close(void) {
64 /* Read functions returns -1 if fail, otherwise the register's value if success */
65 /* Write functions return >= 0 if success, otherwise -1 if fail */
67 int ascodec_write(unsigned int reg
, unsigned int value
)
69 struct codec_req_struct y
;
70 struct codec_req_struct
*p
;
74 return ioctl(afe_dev
, IOCTL_REG_WRITE
, p
);
77 int ascodec_read(unsigned int reg
)
80 struct codec_req_struct y
;
81 struct codec_req_struct
*p
;
84 retval
= ioctl(afe_dev
, IOCTL_REG_READ
, p
);
91 void ascodec_write_pmu(unsigned int index
, unsigned int subreg
,
94 struct codec_req_struct y
;
95 struct codec_req_struct
*p
;
100 ioctl(afe_dev
, IOCTL_SUBREG_WRITE
, p
);
103 int ascodec_read_pmu(unsigned int index
, unsigned int subreg
)
106 struct codec_req_struct y
;
107 struct codec_req_struct
*p
;
111 retval
= ioctl(afe_dev
, IOCTL_SUBREG_READ
, p
);
118 /* Helpers to set/clear bits */
119 void ascodec_set(unsigned int reg
, unsigned int bits
)
121 ascodec_write(reg
, ascodec_read(reg
) | bits
);
124 void ascodec_clear(unsigned int reg
, unsigned int bits
)
126 ascodec_write(reg
, ascodec_read(reg
) & ~bits
);
129 void ascodec_write_masked(unsigned int reg
, unsigned int bits
,
132 ascodec_write(reg
, (ascodec_read(reg
) & ~mask
) | (bits
& mask
));
135 /*FIXME: doesn't work */
136 int ascodec_readbytes(unsigned int index
, unsigned int len
, unsigned char *data
)
140 for (i
=index
; i
<len
; i
++) {
141 data
[i
] = ascodec_read(i
);
142 printf("Register %i: value=%i\n",index
,data
[i
]);
145 printf("TOTAL: %i\n", i
);
152 * After the conversion to interrupts, ascodec_(lock|unlock) are only used by
153 * adc-as3514.c to protect against other threads corrupting the result by using
154 * the ADC at the same time.
156 * Concurrent ascodec_(async_)?(read|write) calls are instead protected
157 * by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically safe
160 void ascodec_lock(void)
165 void ascodec_unlock(void)
167 mutex_unlock(&as_mtx
);
170 /* Read 10-bit channel data */
171 unsigned short adc_read(int channel
)
173 unsigned short data
= 0;
175 if ((unsigned)channel
>= NUM_ADC_CHANNELS
)
181 ascodec_write(AS3514_ADC_0
, (channel
<< 4));
182 unsigned char buf
[2];
185 * The AS3514 ADC will trigger an interrupt when the conversion
186 * is finished, if the corresponding enable bit in IRQ_ENRD2
188 * Previously the code did not wait and this apparently did
189 * not pose any problems, but this should be more correct.
190 * Without the wait the data read back may be completely or
191 * partially (first one of the two bytes) stale.
193 /*FIXME: not implemented*/
194 ascodec_wait_adc_finished();
197 ascodec_readbytes(AS3514_ADC_0
, 2, buf
);
198 data
= (((buf
[0] & 0x3) << 8) | buf
[1]);