diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/hosted/samsungypr/radio-ypr.c | 106 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/radio-ypr.h | 3 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/si4709.h | 82 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/ypr0/i2c-target.h | 30 | ||||
-rw-r--r-- | firmware/target/hosted/samsungypr/ypr1/i2c-target.h | 30 |
5 files changed, 144 insertions, 107 deletions
diff --git a/firmware/target/hosted/samsungypr/radio-ypr.c b/firmware/target/hosted/samsungypr/radio-ypr.c index 4fccf2616f..42d485231d 100644 --- a/firmware/target/hosted/samsungypr/radio-ypr.c +++ b/firmware/target/hosted/samsungypr/radio-ypr.c @@ -21,58 +21,116 @@ * ****************************************************************************/ +/* system includes */ #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> +#include <linux/i2c-dev.h> #include "stdint.h" #include "string.h" -#include "kernel.h" +/* application includes */ +#include "kernel.h" #include "radio-ypr.h" -#include "si4700.h" #include "power.h" +#include "gpio-target.h" +#include "gpio-ypr.h" +#include "panic.h" +#include "i2c-target.h" + +/* 7bits I2C address for Si4709 + * (apparently not selectable by pins or revisions) */ +#define SI4709_I2C_SLAVE_ADDR 0x10 +/** i2c file handle */ static int radio_dev = -1; -void radiodev_open(void) { - radio_dev = open("/dev/si470x", O_RDWR); +/* toggle radio RST pin */ +static void power_toggle(bool set) +{ + /* setup the GPIO port, as in OF */ + gpio_set_iomux(GPIO_FM_BUS_EN, CONFIG_ALT3); + gpio_set_pad(GPIO_FM_BUS_EN, PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH); + gpio_direction_output(GPIO_FM_BUS_EN); + gpio_set(GPIO_FM_BUS_EN, set); } -void radiodev_close(void) { - close(radio_dev); -} +void radiodev_open(void) +{ + int retval = -1; /* ioctl return value */ + + /* open the I2C bus where the chip is attached to */ + radio_dev = open(I2C_BUS_FM_RADIO, O_RDWR); + + if (radio_dev == -1) + { + panicf("%s: failed to open /dev/i2c-1 device - %d", __FUNCTION__, retval); + } + else + { + /* device is open, go on */ + + /* set the slave address for the handle. + * Some other modules might have set the same slave address + * e.g. another module. Let's do a I2C_SLAVE_FORCE which does + * not care about looking for other init'ed i2c slaves */ + retval = ioctl(radio_dev, I2C_SLAVE_FORCE, SI4709_I2C_SLAVE_ADDR); + + if (retval == -1) + { + /* the ioctl call should never fail, if radio_dev is valid */ + panicf("%s: failed to set slave address - %d", __FUNCTION__, retval); + } + else + { + /* initialization completed */ + } + } + + /* i2c subsystem ready, now toggle power to the chip */ + power_toggle(true); + /* 100ms reset delay */ + sleep(HZ/10); -/* High-level registers access */ -void si4709_write_reg(int addr, uint16_t value) { - sSi4709_t r = { .addr = addr, .value = value }; - ioctl(radio_dev, IOCTL_SI4709_WRITE_BYTE, &r); } -uint16_t si4709_read_reg(int addr) { - sSi4709_t r = { .addr = addr, .value = 0 }; - ioctl(radio_dev, IOCTL_SI4709_READ_BYTE, &r); - return r.value; +void radiodev_close(void) +{ + /* power the chip down */ + power_toggle(false); + + /* close the i2c subsystem */ + if (radio_dev != -1) + { + (void)close(radio_dev); + } + else + { + /* not opened */ + } + + /* set back to safe error value */ + radio_dev = -1; } -/* Low-level i2c channel access */ +/* Low-level i2c channel access: write */ int fmradio_i2c_write(unsigned char address, unsigned char* buf, int count) { (void)address; - sSi4709_i2c_t r = { .size = count, .buf = buf }; - return ioctl(radio_dev, IOCTL_SI4709_I2C_WRITE, &r); + return write(radio_dev, buf, count); } +/* Low-level i2c channel access: read */ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) { (void)address; - sSi4709_i2c_t r = { .size = count, .buf = buf }; - return ioctl(radio_dev, IOCTL_SI4709_I2C_READ, &r); + return read(radio_dev, buf, count); } #ifdef HAVE_RDS_CAP /* Register we are going to poll */ -#define STATUSRSSI 0xA +#define STATUSRSSI (0xA) #define STATUSRSSI_RDSR (0x1 << 15) /* Low-level RDS Support */ @@ -89,6 +147,7 @@ static void NORETURN_ATTR rds_thread(void) int timeout = TIMEOUT_BLOCK; struct queue_event ev; bool rds_rdy = false; + struct si4700_dbg_info radio_regs; while (true) { queue_wait_w_tmo(&rds_queue, &ev, timeout); @@ -97,9 +156,10 @@ static void NORETURN_ATTR rds_thread(void) /* power up: timeout after 1 tick, else block indefinitely */ timeout = ev.data ? 1 : TIMEOUT_BLOCK; break; - case SYS_TIMEOUT:; + case SYS_TIMEOUT: /* Captures RDS data and processes it */ - bool rdsr = si4709_read_reg(STATUSRSSI) & STATUSRSSI_RDSR; + si4700_dbg_info(&radio_regs); + bool rdsr = radio_regs.regs[STATUSRSSI] & STATUSRSSI_RDSR; if (rdsr != rds_rdy) { rds_rdy = rdsr; if (rdsr) { diff --git a/firmware/target/hosted/samsungypr/radio-ypr.h b/firmware/target/hosted/samsungypr/radio-ypr.h index 13bcb6dc72..15aeb526ef 100644 --- a/firmware/target/hosted/samsungypr/radio-ypr.h +++ b/firmware/target/hosted/samsungypr/radio-ypr.h @@ -23,7 +23,6 @@ #ifndef __RADIO_YPR0_H__ #define __RADIO_YPR0_H__ -#include "si4709.h" #include "stdint.h" #include "rds.h" #include "si4700.h" @@ -33,4 +32,4 @@ void radiodev_close(void); void si4709_write_reg(int addr, uint16_t value); uint16_t si4709_read_reg(int addr); -#endif /*__RADIO-YPR0_H__*/
\ No newline at end of file +#endif /*__RADIO-YPR0_H__*/ diff --git a/firmware/target/hosted/samsungypr/si4709.h b/firmware/target/hosted/samsungypr/si4709.h deleted file mode 100644 index c27472e856..0000000000 --- a/firmware/target/hosted/samsungypr/si4709.h +++ /dev/null @@ -1,82 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Module header for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) of Samsung YP-R0 - * - * Copyright (c) 2012 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. - * - ****************************************************************************/ - -#ifndef __SI4709_H__ -#define __SI4709_H__ - -#include "stdint.h" - -/* 7bits I2C address */ -#define SI4709_I2C_SLAVE_ADDR 0x10 - -#define SI4702_DEVICEID 0x00 -#define SI4702_CHIPID 0x01 -#define SI4702_POWERCFG 0x02 -#define SI4702_CHANNEL 0x03 -#define SI4702_SYSCONFIG1 0x04 -#define SI4702_SYSCONFIG2 0x05 -#define SI4702_SYSCONFIG3 0x06 -#define SI4702_TEST1 0x07 -#define SI4702_TEST2 0x08 -#define SI4702_B00TCONFIG 0x09 -#define SI4702_STATUSRSSI 0x0A -#define SI4702_READCHAN 0x0B -#define SI4709_REG_NUM 0x10 -#define SI4702_REG_BYTE (SI4709_REG_NUM * 2) -#define SI4702_DEVICE_ID 0x1242 -#define SI4702_RW_REG_NUM (SI4702_STATUSRSSI - SI4702_POWERCFG) -#define SI4702_RW_OFFSET \ - (SI4709_REG_NUM - SI4702_STATUSRSSI + SI4702_POWERCFG) -#define BYTE_TO_WORD(hi, lo) (((hi) << 8) & 0xFF00) | ((lo) & 0x00FF) - -typedef struct { - int addr; - uint16_t value; -}__attribute__((packed)) sSi4709_t; - -typedef struct { - int size; - unsigned char *buf; -}__attribute__((packed)) sSi4709_i2c_t; - -typedef enum -{ - IOCTL_SI4709_INIT = 0, - IOCTL_SI4709_CLOSE, - IOCTL_SI4709_WRITE_BYTE, - IOCTL_SI4709_READ_BYTE, - IOCTL_SI4709_I2C_WRITE, - IOCTL_SI4709_I2C_READ, - - E_IOCTL_SI4709_MAX -} eSi4709_ioctl_t; - -#define DRV_IOCTL_SI4709_MAGIC 'S' - -#define IOCTL_SI4709_INIT _IO(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_INIT) -#define IOCTL_SI4709_CLOSE _IO(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_CLOSE) -#define IOCTL_SI4709_WRITE_BYTE _IOW(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_WRITE_BYTE, sSi4709_t) -#define IOCTL_SI4709_READ_BYTE _IOR(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_READ_BYTE, sSi4709_t) -#define IOCTL_SI4709_I2C_WRITE _IOW(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_I2C_WRITE, sSi4709_i2c_t) -#define IOCTL_SI4709_I2C_READ _IOR(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_I2C_READ, sSi4709_i2c_t) - -#endif /* __SI4709_H__ */
\ No newline at end of file diff --git a/firmware/target/hosted/samsungypr/ypr0/i2c-target.h b/firmware/target/hosted/samsungypr/ypr0/i2c-target.h new file mode 100644 index 0000000000..351988844e --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr0/i2c-target.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module wrapper for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) + * Samsung YP-R0 & Samsung YP-R1 + * + * Copyright (c) 2017 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. + * + ****************************************************************************/ + +#ifndef I2C_TARGET_H_ +#define I2C_TARGET_H_ + +/** Define the FM Radio Chip I2C bus */ +#define I2C_BUS_FM_RADIO ("/dev/i2c-0") + +#endif /* I2C_TARGET_H_ */ diff --git a/firmware/target/hosted/samsungypr/ypr1/i2c-target.h b/firmware/target/hosted/samsungypr/ypr1/i2c-target.h new file mode 100644 index 0000000000..f1fed01cc7 --- /dev/null +++ b/firmware/target/hosted/samsungypr/ypr1/i2c-target.h @@ -0,0 +1,30 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module wrapper for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) + * Samsung YP-R0 & Samsung YP-R1 + * + * Copyright (c) 2017 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. + * + ****************************************************************************/ + +#ifndef I2C_TARGET_H_ +#define I2C_TARGET_H_ + +/** Define the FM Radio Chip I2C bus */ +#define I2C_BUS_FM_RADIO ("/dev/i2c-1") + +#endif /* I2C_TARGET_H_ */ |