From 60592165ca998875e4bc46c4396c5a123a7e9dbb Mon Sep 17 00:00:00 2001 From: Lorenzo Miori Date: Sat, 23 Feb 2013 16:59:49 +0100 Subject: Samsung YP-R0 hosted target code refactoring As per title this patch aims at splitting common target code and specific target code in a better way to support future ports within the same environment (e.g. Samsung YP-R1 where the Linux and the SoC are the same, with differences in hardware devices handling) Change-Id: I67b4918c46403b184d3d8f42ab5aae7d01037fd0 Reviewed-on: http://gerrit.rockbox.org/409 Reviewed-by: Thomas Martitz Tested-by: Thomas Martitz --- .../target/hosted/samsungypr/ypr0/ascodec-ypr0.c | 167 +++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c (limited to 'firmware/target/hosted/samsungypr/ypr0/ascodec-ypr0.c') 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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module wrapper for AS3543 audio codec, using /dev/afe (afe.ko) of Samsung YP-R0 + * + * Copyright (c) 2011-2013 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" + +static int afe_dev = -1; + +/* Structure used for ioctl module call */ +struct codec_req_struct { + 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 + +/* Open device */ +void ascodec_init(void) +{ + afe_dev = open("/dev/afe", O_RDWR); +} + +/* Close device */ +void ascodec_close(void) +{ + if (afe_dev >= 0) + close(afe_dev); +} + +/* Write register. + * Returns >= 0 if success, -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); +} + +/* Read register. + * Returns -1 if fail, otherwise the register's value if success + */ +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; +} + +/* Write PMU register */ +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); +} + +/* Read PMU register */ +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) +{ +} -- cgit v1.2.3