856bb42037
Change-Id: I327d58fde66fc7fa65f91e0ca724c3fd8066ccf6
163 lines
4.3 KiB
C
163 lines
4.3 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
*
|
|
* Module wrapper for AS3543 audio codec, using /dev/afe (afe.ko) of Samsung YP-R0
|
|
*
|
|
* Copyright (c) 2011 Lorenzo Miori
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "fcntl.h"
|
|
#include "unistd.h"
|
|
#include "stdio.h"
|
|
#include "string.h"
|
|
#include "sys/ioctl.h"
|
|
#include "stdlib.h"
|
|
|
|
#include "ascodec.h"
|
|
|
|
int afe_dev = -1;
|
|
|
|
/* ioctl parameter struct */
|
|
struct codec_req_struct {
|
|
/* This works for every kind of afe.ko module requests */
|
|
unsigned char reg; /* Main register address */
|
|
unsigned char subreg; /* Set this only if you are reading/writing a PMU register*/
|
|
unsigned char value; /* To be read if reading a register; to be set if writing to a register */
|
|
} __attribute__((packed));
|
|
|
|
|
|
/* Write to a normal register */
|
|
#define IOCTL_REG_WRITE 0x40034101
|
|
/* Write to a PMU register */
|
|
#define IOCTL_SUBREG_WRITE 0x40034103
|
|
/* Read from a normal register */
|
|
#define IOCTL_REG_READ 0x80034102
|
|
/* Read from a PMU register */
|
|
#define IOCTL_SUBREG_READ 0x80034103
|
|
|
|
|
|
void ascodec_init(void)
|
|
{
|
|
afe_dev = open("/dev/afe", O_RDWR);
|
|
}
|
|
|
|
void ascodec_close(void)
|
|
{
|
|
if (afe_dev >= 0) {
|
|
close(afe_dev);
|
|
}
|
|
}
|
|
|
|
/* Read functions returns -1 if fail, otherwise the register's value if success */
|
|
/* Write functions return >= 0 if success, otherwise -1 if fail */
|
|
|
|
int ascodec_write(unsigned int reg, unsigned int value)
|
|
{
|
|
struct codec_req_struct r = { .reg = reg, .value = value };
|
|
return ioctl(afe_dev, IOCTL_REG_WRITE, &r);
|
|
}
|
|
|
|
int ascodec_read(unsigned int reg)
|
|
{
|
|
struct codec_req_struct r = { .reg = reg };
|
|
int retval = ioctl(afe_dev, IOCTL_REG_READ, &r);
|
|
if (retval >= 0)
|
|
return r.value;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
|
unsigned int value)
|
|
{
|
|
struct codec_req_struct r = {.reg = index, .subreg = subreg, .value = value};
|
|
ioctl(afe_dev, IOCTL_SUBREG_WRITE, &r);
|
|
}
|
|
|
|
int ascodec_read_pmu(unsigned int index, unsigned int subreg)
|
|
{
|
|
struct codec_req_struct r = { .reg = index, .subreg = subreg, };
|
|
int retval = ioctl(afe_dev, IOCTL_SUBREG_READ, &r);
|
|
if (retval >= 0)
|
|
return r.value;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
|
|
{
|
|
int i, val, ret = 0;
|
|
|
|
for (i = 0; i < (int)len; i++)
|
|
{
|
|
val = ascodec_read(i + index);
|
|
if (val >= 0) data[i] = val;
|
|
else ret = -1;
|
|
}
|
|
|
|
return (ret ?: (int)len);
|
|
}
|
|
|
|
/*
|
|
* NOTE:
|
|
* After the conversion to interrupts, ascodec_(lock|unlock) are only used by
|
|
* adc-as3514.c to protect against other threads corrupting the result by using
|
|
* the ADC at the same time. this adc_read() doesn't yield but blocks, so
|
|
* lock/unlock is not needed
|
|
*
|
|
* Additionally, concurrent ascodec_?(read|write) calls are instead protected
|
|
* by the R0's Kernel I2C driver for ascodec (mutexed), so it's automatically
|
|
* safe
|
|
*/
|
|
|
|
void ascodec_lock(void)
|
|
{
|
|
}
|
|
|
|
void ascodec_unlock(void)
|
|
{
|
|
}
|
|
|
|
bool ascodec_chg_status(void)
|
|
{
|
|
return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS;
|
|
}
|
|
|
|
bool ascodec_endofch(void)
|
|
{
|
|
return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH;
|
|
}
|
|
|
|
void ascodec_monitor_endofch(void)
|
|
{
|
|
ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH);
|
|
}
|
|
|
|
|
|
void ascodec_write_charger(int value)
|
|
{
|
|
ascodec_write_pmu(AS3543_CHARGER, 1, value);
|
|
}
|
|
|
|
int ascodec_read_charger(void)
|
|
{
|
|
return ascodec_read_pmu(AS3543_CHARGER, 1);
|
|
}
|
|
|
|
void ascodec_wait_adc_finished(void)
|
|
{
|
|
}
|