summaryrefslogtreecommitdiff
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 @@
21 * 21 *
22 ****************************************************************************/ 22 ****************************************************************************/
23 23
24/* system includes */
24#include <unistd.h> 25#include <unistd.h>
25#include <fcntl.h> 26#include <fcntl.h>
26#include <sys/ioctl.h> 27#include <sys/ioctl.h>
28#include <linux/i2c-dev.h>
27#include "stdint.h" 29#include "stdint.h"
28#include "string.h" 30#include "string.h"
29#include "kernel.h"
30 31
32/* application includes */
33#include "kernel.h"
31#include "radio-ypr.h" 34#include "radio-ypr.h"
32#include "si4700.h"
33#include "power.h" 35#include "power.h"
36#include "gpio-target.h"
37#include "gpio-ypr.h"
38#include "panic.h"
39#include "i2c-target.h"
40
41/* 7bits I2C address for Si4709
42 * (apparently not selectable by pins or revisions) */
43#define SI4709_I2C_SLAVE_ADDR 0x10
34 44
45/** i2c file handle */
35static int radio_dev = -1; 46static int radio_dev = -1;
36 47
37void radiodev_open(void) { 48/* toggle radio RST pin */
38 radio_dev = open("/dev/si470x", O_RDWR); 49static void power_toggle(bool set)
50{
51 /* setup the GPIO port, as in OF */
52 gpio_set_iomux(GPIO_FM_BUS_EN, CONFIG_ALT3);
53 gpio_set_pad(GPIO_FM_BUS_EN, PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH);
54 gpio_direction_output(GPIO_FM_BUS_EN);
55 gpio_set(GPIO_FM_BUS_EN, set);
39} 56}
40 57
41void radiodev_close(void) { 58void radiodev_open(void)
42 close(radio_dev); 59{
43} 60 int retval = -1; /* ioctl return value */
61
62 /* open the I2C bus where the chip is attached to */
63 radio_dev = open(I2C_BUS_FM_RADIO, O_RDWR);
64
65 if (radio_dev == -1)
66 {
67 panicf("%s: failed to open /dev/i2c-1 device - %d", __FUNCTION__, retval);
68 }
69 else
70 {
71 /* device is open, go on */
72
73 /* set the slave address for the handle.
74 * Some other modules might have set the same slave address
75 * e.g. another module. Let's do a I2C_SLAVE_FORCE which does
76 * not care about looking for other init'ed i2c slaves */
77 retval = ioctl(radio_dev, I2C_SLAVE_FORCE, SI4709_I2C_SLAVE_ADDR);
78
79 if (retval == -1)
80 {
81 /* the ioctl call should never fail, if radio_dev is valid */
82 panicf("%s: failed to set slave address - %d", __FUNCTION__, retval);
83 }
84 else
85 {
86 /* initialization completed */
87 }
88 }
89
90 /* i2c subsystem ready, now toggle power to the chip */
91 power_toggle(true);
92 /* 100ms reset delay */
93 sleep(HZ/10);
44 94
45/* High-level registers access */
46void si4709_write_reg(int addr, uint16_t value) {
47 sSi4709_t r = { .addr = addr, .value = value };
48 ioctl(radio_dev, IOCTL_SI4709_WRITE_BYTE, &r);
49} 95}
50 96
51uint16_t si4709_read_reg(int addr) { 97void radiodev_close(void)
52 sSi4709_t r = { .addr = addr, .value = 0 }; 98{
53 ioctl(radio_dev, IOCTL_SI4709_READ_BYTE, &r); 99 /* power the chip down */
54 return r.value; 100 power_toggle(false);
101
102 /* close the i2c subsystem */
103 if (radio_dev != -1)
104 {
105 (void)close(radio_dev);
106 }
107 else
108 {
109 /* not opened */
110 }
111
112 /* set back to safe error value */
113 radio_dev = -1;
55} 114}
56 115
57/* Low-level i2c channel access */ 116/* Low-level i2c channel access: write */
58int fmradio_i2c_write(unsigned char address, unsigned char* buf, int count) 117int fmradio_i2c_write(unsigned char address, unsigned char* buf, int count)
59{ 118{
60 (void)address; 119 (void)address;
61 sSi4709_i2c_t r = { .size = count, .buf = buf }; 120 return write(radio_dev, buf, count);
62 return ioctl(radio_dev, IOCTL_SI4709_I2C_WRITE, &r);
63} 121}
64 122
123/* Low-level i2c channel access: read */
65int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) 124int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
66{ 125{
67 (void)address; 126 (void)address;
68 sSi4709_i2c_t r = { .size = count, .buf = buf }; 127 return read(radio_dev, buf, count);
69 return ioctl(radio_dev, IOCTL_SI4709_I2C_READ, &r);
70} 128}
71 129
72#ifdef HAVE_RDS_CAP 130#ifdef HAVE_RDS_CAP
73 131
74/* Register we are going to poll */ 132/* Register we are going to poll */
75#define STATUSRSSI 0xA 133#define STATUSRSSI (0xA)
76#define STATUSRSSI_RDSR (0x1 << 15) 134#define STATUSRSSI_RDSR (0x1 << 15)
77 135
78/* Low-level RDS Support */ 136/* Low-level RDS Support */
@@ -89,6 +147,7 @@ static void NORETURN_ATTR rds_thread(void)
89 int timeout = TIMEOUT_BLOCK; 147 int timeout = TIMEOUT_BLOCK;
90 struct queue_event ev; 148 struct queue_event ev;
91 bool rds_rdy = false; 149 bool rds_rdy = false;
150 struct si4700_dbg_info radio_regs;
92 151
93 while (true) { 152 while (true) {
94 queue_wait_w_tmo(&rds_queue, &ev, timeout); 153 queue_wait_w_tmo(&rds_queue, &ev, timeout);
@@ -97,9 +156,10 @@ static void NORETURN_ATTR rds_thread(void)
97 /* power up: timeout after 1 tick, else block indefinitely */ 156 /* power up: timeout after 1 tick, else block indefinitely */
98 timeout = ev.data ? 1 : TIMEOUT_BLOCK; 157 timeout = ev.data ? 1 : TIMEOUT_BLOCK;
99 break; 158 break;
100 case SYS_TIMEOUT:; 159 case SYS_TIMEOUT:
101 /* Captures RDS data and processes it */ 160 /* Captures RDS data and processes it */
102 bool rdsr = si4709_read_reg(STATUSRSSI) & STATUSRSSI_RDSR; 161 si4700_dbg_info(&radio_regs);
162 bool rdsr = radio_regs.regs[STATUSRSSI] & STATUSRSSI_RDSR;
103 if (rdsr != rds_rdy) { 163 if (rdsr != rds_rdy) {
104 rds_rdy = rdsr; 164 rds_rdy = rdsr;
105 if (rdsr) { 165 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 @@
23#ifndef __RADIO_YPR0_H__ 23#ifndef __RADIO_YPR0_H__
24#define __RADIO_YPR0_H__ 24#define __RADIO_YPR0_H__
25 25
26#include "si4709.h"
27#include "stdint.h" 26#include "stdint.h"
28#include "rds.h" 27#include "rds.h"
29#include "si4700.h" 28#include "si4700.h"
@@ -33,4 +32,4 @@ void radiodev_close(void);
33void si4709_write_reg(int addr, uint16_t value); 32void si4709_write_reg(int addr, uint16_t value);
34uint16_t si4709_read_reg(int addr); 33uint16_t si4709_read_reg(int addr);
35 34
36#endif /*__RADIO-YPR0_H__*/ \ No newline at end of file 35#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Module header for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) of Samsung YP-R0
10 *
11 * Copyright (c) 2012 Lorenzo Miori
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#ifndef __SI4709_H__
24#define __SI4709_H__
25
26#include "stdint.h"
27
28/* 7bits I2C address */
29#define SI4709_I2C_SLAVE_ADDR 0x10
30
31#define SI4702_DEVICEID 0x00
32#define SI4702_CHIPID 0x01
33#define SI4702_POWERCFG 0x02
34#define SI4702_CHANNEL 0x03
35#define SI4702_SYSCONFIG1 0x04
36#define SI4702_SYSCONFIG2 0x05
37#define SI4702_SYSCONFIG3 0x06
38#define SI4702_TEST1 0x07
39#define SI4702_TEST2 0x08
40#define SI4702_B00TCONFIG 0x09
41#define SI4702_STATUSRSSI 0x0A
42#define SI4702_READCHAN 0x0B
43#define SI4709_REG_NUM 0x10
44#define SI4702_REG_BYTE (SI4709_REG_NUM * 2)
45#define SI4702_DEVICE_ID 0x1242
46#define SI4702_RW_REG_NUM (SI4702_STATUSRSSI - SI4702_POWERCFG)
47#define SI4702_RW_OFFSET \
48 (SI4709_REG_NUM - SI4702_STATUSRSSI + SI4702_POWERCFG)
49#define BYTE_TO_WORD(hi, lo) (((hi) << 8) & 0xFF00) | ((lo) & 0x00FF)
50
51typedef struct {
52 int addr;
53 uint16_t value;
54}__attribute__((packed)) sSi4709_t;
55
56typedef struct {
57 int size;
58 unsigned char *buf;
59}__attribute__((packed)) sSi4709_i2c_t;
60
61typedef enum
62{
63 IOCTL_SI4709_INIT = 0,
64 IOCTL_SI4709_CLOSE,
65 IOCTL_SI4709_WRITE_BYTE,
66 IOCTL_SI4709_READ_BYTE,
67 IOCTL_SI4709_I2C_WRITE,
68 IOCTL_SI4709_I2C_READ,
69
70 E_IOCTL_SI4709_MAX
71} eSi4709_ioctl_t;
72
73#define DRV_IOCTL_SI4709_MAGIC 'S'
74
75#define IOCTL_SI4709_INIT _IO(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_INIT)
76#define IOCTL_SI4709_CLOSE _IO(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_CLOSE)
77#define IOCTL_SI4709_WRITE_BYTE _IOW(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_WRITE_BYTE, sSi4709_t)
78#define IOCTL_SI4709_READ_BYTE _IOR(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_READ_BYTE, sSi4709_t)
79#define IOCTL_SI4709_I2C_WRITE _IOW(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_I2C_WRITE, sSi4709_i2c_t)
80#define IOCTL_SI4709_I2C_READ _IOR(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_I2C_READ, sSi4709_i2c_t)
81
82#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Module wrapper for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko)
10 * Samsung YP-R0 & Samsung YP-R1
11 *
12 * Copyright (c) 2017 Lorenzo Miori
13 *
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.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#ifndef I2C_TARGET_H_
25#define I2C_TARGET_H_
26
27/** Define the FM Radio Chip I2C bus */
28#define I2C_BUS_FM_RADIO ("/dev/i2c-0")
29
30#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Module wrapper for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko)
10 * Samsung YP-R0 & Samsung YP-R1
11 *
12 * Copyright (c) 2017 Lorenzo Miori
13 *
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.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#ifndef I2C_TARGET_H_
25#define I2C_TARGET_H_
26
27/** Define the FM Radio Chip I2C bus */
28#define I2C_BUS_FM_RADIO ("/dev/i2c-1")
29
30#endif /* I2C_TARGET_H_ */