2019-05-27 08:55:06 +02:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
2009-08-09 14:22:20 -03:00
/*
* drivers / media / radio / si470x / radio - si470x . h
*
* Driver for radios with Silicon Labs Si470x FM Radio Receivers
*
* Copyright ( c ) 2009 Tobias Lorenz < tobias . lorenz @ gmx . net >
*/
/* driver definitions */
# define DRIVER_NAME "radio-si470x"
/* kernel includes */
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/init.h>
2009-12-14 14:08:13 -03:00
# include <linux/sched.h>
2009-08-09 14:22:20 -03:00
# include <linux/slab.h>
# include <linux/input.h>
# include <linux/videodev2.h>
# include <linux/mutex.h>
# include <media/v4l2-common.h>
# include <media/v4l2-ioctl.h>
2012-05-04 09:16:57 -03:00
# include <media/v4l2-ctrls.h>
# include <media/v4l2-event.h>
# include <media/v4l2-device.h>
2009-08-09 14:22:20 -03:00
# include <asm/unaligned.h>
2009-08-10 18:44:14 -03:00
2009-08-09 14:22:20 -03:00
/**************************************************************************
* Register Definitions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define RADIO_REGISTER_SIZE 2 /* 16 register bit width */
# define RADIO_REGISTER_NUM 16 /* DEVICEID ... RDSD */
# define RDS_REGISTER_NUM 6 /* STATUSRSSI ... RDSD */
# define DEVICEID 0 /* Device ID */
# define DEVICEID_PN 0xf000 /* bits 15..12: Part Number */
# define DEVICEID_MFGID 0x0fff /* bits 11..00: Manufacturer ID */
2015-06-22 15:25:31 -03:00
# define SI_CHIPID 1 /* Chip ID */
# define SI_CHIPID_REV 0xfc00 /* bits 15..10: Chip Version */
# define SI_CHIPID_DEV 0x0200 /* bits 09..09: Device */
# define SI_CHIPID_FIRMWARE 0x01ff /* bits 08..00: Firmware Version */
2009-08-09 14:22:20 -03:00
# define POWERCFG 2 /* Power Configuration */
# define POWERCFG_DSMUTE 0x8000 /* bits 15..15: Softmute Disable */
# define POWERCFG_DMUTE 0x4000 /* bits 14..14: Mute Disable */
# define POWERCFG_MONO 0x2000 /* bits 13..13: Mono Select */
# define POWERCFG_RDSM 0x0800 /* bits 11..11: RDS Mode (Si4701 only) */
# define POWERCFG_SKMODE 0x0400 /* bits 10..10: Seek Mode */
# define POWERCFG_SEEKUP 0x0200 /* bits 09..09: Seek Direction */
# define POWERCFG_SEEK 0x0100 /* bits 08..08: Seek */
# define POWERCFG_DISABLE 0x0040 /* bits 06..06: Powerup Disable */
# define POWERCFG_ENABLE 0x0001 /* bits 00..00: Powerup Enable */
# define CHANNEL 3 /* Channel */
# define CHANNEL_TUNE 0x8000 /* bits 15..15: Tune */
# define CHANNEL_CHAN 0x03ff /* bits 09..00: Channel Select */
# define SYSCONFIG1 4 /* System Configuration 1 */
# define SYSCONFIG1_RDSIEN 0x8000 /* bits 15..15: RDS Interrupt Enable (Si4701 only) */
# define SYSCONFIG1_STCIEN 0x4000 /* bits 14..14: Seek/Tune Complete Interrupt Enable */
# define SYSCONFIG1_RDS 0x1000 /* bits 12..12: RDS Enable (Si4701 only) */
# define SYSCONFIG1_DE 0x0800 /* bits 11..11: De-emphasis (0=75us 1=50us) */
# define SYSCONFIG1_AGCD 0x0400 /* bits 10..10: AGC Disable */
# define SYSCONFIG1_BLNDADJ 0x00c0 /* bits 07..06: Stereo/Mono Blend Level Adjustment */
# define SYSCONFIG1_GPIO3 0x0030 /* bits 05..04: General Purpose I/O 3 */
# define SYSCONFIG1_GPIO2 0x000c /* bits 03..02: General Purpose I/O 2 */
2018-03-02 10:25:43 -05:00
# define SYSCONFIG1_GPIO2_DIS 0x0000 /* Disable GPIO 2 interrupt */
# define SYSCONFIG1_GPIO2_INT 0x0004 /* Enable STC/RDS interrupt */
2009-08-09 14:22:20 -03:00
# define SYSCONFIG1_GPIO1 0x0003 /* bits 01..00: General Purpose I/O 1 */
# define SYSCONFIG2 5 /* System Configuration 2 */
# define SYSCONFIG2_SEEKTH 0xff00 /* bits 15..08: RSSI Seek Threshold */
2012-07-12 16:55:47 -03:00
# define SYSCONFIG2_BAND 0x00c0 /* bits 07..06: Band Select */
2009-08-09 14:22:20 -03:00
# define SYSCONFIG2_SPACE 0x0030 /* bits 05..04: Channel Spacing */
# define SYSCONFIG2_VOLUME 0x000f /* bits 03..00: Volume */
# define SYSCONFIG3 6 /* System Configuration 3 */
# define SYSCONFIG3_SMUTER 0xc000 /* bits 15..14: Softmute Attack/Recover Rate */
# define SYSCONFIG3_SMUTEA 0x3000 /* bits 13..12: Softmute Attenuation */
# define SYSCONFIG3_SKSNR 0x00f0 /* bits 07..04: Seek SNR Threshold */
# define SYSCONFIG3_SKCNT 0x000f /* bits 03..00: Seek FM Impulse Detection Threshold */
# define TEST1 7 /* Test 1 */
# define TEST1_AHIZEN 0x4000 /* bits 14..14: Audio High-Z Enable */
# define TEST2 8 /* Test 2 */
/* TEST2 only contains reserved bits */
# define BOOTCONFIG 9 /* Boot Configuration */
/* BOOTCONFIG only contains reserved bits */
# define STATUSRSSI 10 /* Status RSSI */
# define STATUSRSSI_RDSR 0x8000 /* bits 15..15: RDS Ready (Si4701 only) */
# define STATUSRSSI_STC 0x4000 /* bits 14..14: Seek/Tune Complete */
# define STATUSRSSI_SF 0x2000 /* bits 13..13: Seek Fail/Band Limit */
# define STATUSRSSI_AFCRL 0x1000 /* bits 12..12: AFC Rail */
# define STATUSRSSI_RDSS 0x0800 /* bits 11..11: RDS Synchronized (Si4701 only) */
# define STATUSRSSI_BLERA 0x0600 /* bits 10..09: RDS Block A Errors (Si4701 only) */
# define STATUSRSSI_ST 0x0100 /* bits 08..08: Stereo Indicator */
# define STATUSRSSI_RSSI 0x00ff /* bits 07..00: RSSI (Received Signal Strength Indicator) */
# define READCHAN 11 /* Read Channel */
# define READCHAN_BLERB 0xc000 /* bits 15..14: RDS Block D Errors (Si4701 only) */
# define READCHAN_BLERC 0x3000 /* bits 13..12: RDS Block C Errors (Si4701 only) */
# define READCHAN_BLERD 0x0c00 /* bits 11..10: RDS Block B Errors (Si4701 only) */
# define READCHAN_READCHAN 0x03ff /* bits 09..00: Read Channel */
# define RDSA 12 /* RDSA */
# define RDSA_RDSA 0xffff /* bits 15..00: RDS Block A Data (Si4701 only) */
# define RDSB 13 /* RDSB */
# define RDSB_RDSB 0xffff /* bits 15..00: RDS Block B Data (Si4701 only) */
# define RDSC 14 /* RDSC */
# define RDSC_RDSC 0xffff /* bits 15..00: RDS Block C Data (Si4701 only) */
# define RDSD 15 /* RDSD */
# define RDSD_RDSD 0xffff /* bits 15..00: RDS Block D Data (Si4701 only) */
2009-08-10 18:44:14 -03:00
2009-08-09 14:22:20 -03:00
/**************************************************************************
* General Driver Definitions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* si470x_device - private data
*/
struct si470x_device {
2012-05-04 09:16:57 -03:00
struct v4l2_device v4l2_dev ;
struct video_device videodev ;
struct v4l2_ctrl_handler hdl ;
2012-07-12 16:55:48 -03:00
int band ;
2009-08-10 18:44:14 -03:00
/* Silabs internal registers (0..15) */
unsigned short registers [ RADIO_REGISTER_NUM ] ;
/* RDS receive buffer */
wait_queue_head_t read_queue ;
struct mutex lock ; /* buffer locking */
unsigned char * buffer ; /* size is always multiple of three */
unsigned int buf_size ;
unsigned int rd_index ;
unsigned int wr_index ;
2009-08-09 14:23:35 -03:00
2011-03-11 03:54:46 -03:00
struct completion completion ;
2012-06-14 09:43:11 -03:00
bool status_rssi_auto_update ; /* Does RSSI get updated automatic? */
2011-03-11 03:54:46 -03:00
2018-04-05 15:08:12 -04:00
/* si470x ops */
int ( * get_register ) ( struct si470x_device * radio , int regnr ) ;
int ( * set_register ) ( struct si470x_device * radio , int regnr ) ;
int ( * fops_open ) ( struct file * file ) ;
int ( * fops_release ) ( struct file * file ) ;
int ( * vidioc_querycap ) ( struct file * file , void * priv ,
struct v4l2_capability * capability ) ;
2013-01-24 19:28:57 -03:00
# if IS_ENABLED(CONFIG_USB_SI470X)
2009-08-09 14:22:20 -03:00
/* reference to USB and video device */
struct usb_device * usbdev ;
struct usb_interface * intf ;
2013-12-13 08:06:07 -03:00
char * usb_buf ;
2009-08-09 14:22:20 -03:00
/* Interrupt endpoint handling */
char * int_in_buffer ;
struct usb_endpoint_descriptor * int_in_endpoint ;
struct urb * int_in_urb ;
int int_in_running ;
/* scratch page */
unsigned char software_version ;
unsigned char hardware_version ;
2009-08-09 14:23:35 -03:00
# endif
2009-08-09 14:22:20 -03:00
2013-01-24 19:28:57 -03:00
# if IS_ENABLED(CONFIG_I2C_SI470X)
2009-08-10 18:44:14 -03:00
struct i2c_client * client ;
2018-12-07 11:58:11 -02:00
struct gpio_desc * gpio_reset ;
2009-08-10 18:44:14 -03:00
# endif
2009-08-09 14:22:20 -03:00
} ;
2009-08-10 18:44:14 -03:00
/**************************************************************************
* Firmware Versions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-07-11 11:47:38 -03:00
# define RADIO_FW_VERSION 12
2009-08-10 18:44:14 -03:00
/**************************************************************************
* Frequency Multiplicator
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-08-09 14:22:20 -03:00
/*
* The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW ,
* 62.5 kHz otherwise .
* The tuner is able to have a channel spacing of 50 , 100 or 200 kHz .
* tuner - > capability is therefore set to V4L2_TUNER_CAP_LOW
* The FREQ_MUL is then : 1 MHz / 62.5 Hz = 16000
*/
# define FREQ_MUL (1000000 / 62.5)
/**************************************************************************
* Common Functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-09-27 04:38:29 -04:00
extern const struct video_device si470x_viddev_template ;
2012-05-04 09:16:57 -03:00
extern const struct v4l2_ctrl_ops si470x_ctrl_ops ;
2009-08-09 14:23:02 -03:00
int si470x_disconnect_check ( struct si470x_device * radio ) ;
2009-08-09 14:22:20 -03:00
int si470x_set_freq ( struct si470x_device * radio , unsigned int freq ) ;
int si470x_start ( struct si470x_device * radio ) ;
int si470x_stop ( struct si470x_device * radio ) ;