summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/target/hosted/samsungypr/radio-ypr.c106
-rw-r--r--firmware/target/hosted/samsungypr/radio-ypr.h3
-rw-r--r--firmware/target/hosted/samsungypr/si4709.h82
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/i2c-target.h30
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/i2c-target.h30
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_ */