linux/drivers/media/radio/si470x/radio-si470x-common.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  drivers/media/radio/si470x/radio-si470x-common.c
 *
 *  Driver for radios with Silicon Labs Si470x FM Radio Receivers
 *
 *  Copyright (c) 2009 Tobias Lorenz <[email protected]>
 *  Copyright (c) 2012 Hans de Goede <[email protected]>
 */


/*
 * History:
 * 2008-01-12	Tobias Lorenz <[email protected]>
 *		Version 1.0.0
 *		- First working version
 * 2008-01-13	Tobias Lorenz <[email protected]>
 *		Version 1.0.1
 *		- Improved error handling, every function now returns errno
 *		- Improved multi user access (start/mute/stop)
 *		- Channel doesn't get lost anymore after start/mute/stop
 *		- RDS support added (polling mode via interrupt EP 1)
 *		- marked default module parameters with *value*
 *		- switched from bit structs to bit masks
 *		- header file cleaned and integrated
 * 2008-01-14	Tobias Lorenz <[email protected]>
 *		Version 1.0.2
 *		- hex values are now lower case
 *		- commented USB ID for ADS/Tech moved on todo list
 *		- blacklisted si470x in hid-quirks.c
 *		- rds buffer handling functions integrated into *_work, *_read
 *		- rds_command in si470x_poll exchanged against simple retval
 *		- check for firmware version 15
 *		- code order and prototypes still remain the same
 *		- spacing and bottom of band codes remain the same
 * 2008-01-16	Tobias Lorenz <[email protected]>
 *		Version 1.0.3
 *		- code reordered to avoid function prototypes
 *		- switch/case defaults are now more user-friendly
 *		- unified comment style
 *		- applied all checkpatch.pl v1.12 suggestions
 *		  except the warning about the too long lines with bit comments
 *		- renamed FMRADIO to RADIO to cut line length (checkpatch.pl)
 * 2008-01-22	Tobias Lorenz <[email protected]>
 *		Version 1.0.4
 *		- avoid poss. locking when doing copy_to_user which may sleep
 *		- RDS is automatically activated on read now
 *		- code cleaned of unnecessary rds_commands
 *		- USB Vendor/Product ID for ADS/Tech FM Radio Receiver verified
 *		  (thanks to Guillaume RAMOUSSE)
 * 2008-01-27	Tobias Lorenz <[email protected]>
 *		Version 1.0.5
 *		- number of seek_retries changed to tune_timeout
 *		- fixed problem with incomplete tune operations by own buffers
 *		- optimization of variables and printf types
 *		- improved error logging
 * 2008-01-31	Tobias Lorenz <[email protected]>
 *		Oliver Neukum <[email protected]>
 *		Version 1.0.6
 *		- fixed coverity checker warnings in *_usb_driver_disconnect
 *		- probe()/open() race by correct ordering in probe()
 *		- DMA coherency rules by separate allocation of all buffers
 *		- use of endianness macros
 *		- abuse of spinlock, replaced by mutex
 *		- racy handling of timer in disconnect,
 *		  replaced by delayed_work
 *		- racy interruptible_sleep_on(),
 *		  replaced with wait_event_interruptible()
 *		- handle signals in read()
 * 2008-02-08	Tobias Lorenz <[email protected]>
 *		Oliver Neukum <[email protected]>
 *		Version 1.0.7
 *		- usb autosuspend support
 *		- unplugging fixed
 * 2008-05-07	Tobias Lorenz <[email protected]>
 *		Version 1.0.8
 *		- hardware frequency seek support
 *		- afc indication
 *		- more safety checks, let si470x_get_freq return errno
 *		- vidioc behavior corrected according to v4l2 spec
 * 2008-10-20	Alexey Klimov <[email protected]>
 *		- add support for KWorld USB FM Radio FM700
 *		- blacklisted KWorld radio in hid-core.c and hid-ids.h
 * 2008-12-03	Mark Lord <[email protected]>
 *		- add support for DealExtreme USB Radio
 * 2009-01-31	Bob Ross <[email protected]>
 *		- correction of stereo detection/setting
 *		- correction of signal strength indicator scaling
 * 2009-01-31	Rick Bronson <[email protected]>
 *		Tobias Lorenz <[email protected]>
 *		- add LED status output
 *		- get HW/SW version from scratchpad
 * 2009-06-16   Edouard Lafargue <[email protected]>
 *		Version 1.0.10
 *		- add support for interrupt mode for RDS endpoint,
 *                instead of polling.
 *                Improves RDS reception significantly
 */


/* kernel includes */
#include "radio-si470x.h"

/**************************************************************************
 * Module Parameters
 **************************************************************************/

/* Spacing (kHz) */
/* 0: 200 kHz (USA, Australia) */
/* 1: 100 kHz (Europe, Japan) */
/* 2:  50 kHz */
static unsigned short space =;
module_param(space, ushort, 0444);
MODULE_PARM_DESC();

/* De-emphasis */
/* 0: 75 us (USA) */
/* 1: 50 us (Europe, Australia, Japan) */
static unsigned short de =;
module_param(de, ushort, 0444);
MODULE_PARM_DESC();

/* Tune timeout */
static unsigned int tune_timeout =;
module_param(tune_timeout, uint, 0644);
MODULE_PARM_DESC();

/* Seek timeout */
static unsigned int seek_timeout =;
module_param(seek_timeout, uint, 0644);
MODULE_PARM_DESC();

static const struct v4l2_frequency_band bands[] =;

/**************************************************************************
 * Generic Functions
 **************************************************************************/

/*
 * si470x_set_band - set the band
 */
static int si470x_set_band(struct si470x_device *radio, int band)
{}

/*
 * si470x_set_chan - set the channel
 */
static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
{}

/*
 * si470x_get_step - get channel spacing
 */
static unsigned int si470x_get_step(struct si470x_device *radio)
{}


/*
 * si470x_get_freq - get the frequency
 */
static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
{}


/*
 * si470x_set_freq - set the frequency
 */
int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
{}
EXPORT_SYMBOL_GPL();


/*
 * si470x_set_seek - set seek
 */
static int si470x_set_seek(struct si470x_device *radio,
			   const struct v4l2_hw_freq_seek *seek)
{}


/*
 * si470x_start - switch on radio
 */
int si470x_start(struct si470x_device *radio)
{}
EXPORT_SYMBOL_GPL();


/*
 * si470x_stop - switch off radio
 */
int si470x_stop(struct si470x_device *radio)
{}
EXPORT_SYMBOL_GPL();


/*
 * si470x_rds_on - switch on rds reception
 */
static int si470x_rds_on(struct si470x_device *radio)
{}



/**************************************************************************
 * File Operations Interface
 **************************************************************************/

/*
 * si470x_fops_read - read RDS data
 */
static ssize_t si470x_fops_read(struct file *file, char __user *buf,
		size_t count, loff_t *ppos)
{}


/*
 * si470x_fops_poll - poll RDS data
 */
static __poll_t si470x_fops_poll(struct file *file,
		struct poll_table_struct *pts)
{}


static int si470x_fops_open(struct file *file)
{}


/*
 * si470x_fops_release - file release
 */
static int si470x_fops_release(struct file *file)
{}


/*
 * si470x_fops - file operations interface
 */
static const struct v4l2_file_operations si470x_fops =;



/**************************************************************************
 * Video4Linux Interface
 **************************************************************************/


static int si470x_s_ctrl(struct v4l2_ctrl *ctrl)
{}


/*
 * si470x_vidioc_g_tuner - get tuner attributes
 */
static int si470x_vidioc_g_tuner(struct file *file, void *priv,
		struct v4l2_tuner *tuner)
{}


/*
 * si470x_vidioc_s_tuner - set tuner attributes
 */
static int si470x_vidioc_s_tuner(struct file *file, void *priv,
		const struct v4l2_tuner *tuner)
{}


/*
 * si470x_vidioc_g_frequency - get tuner or modulator radio frequency
 */
static int si470x_vidioc_g_frequency(struct file *file, void *priv,
		struct v4l2_frequency *freq)
{}


/*
 * si470x_vidioc_s_frequency - set tuner or modulator radio frequency
 */
static int si470x_vidioc_s_frequency(struct file *file, void *priv,
		const struct v4l2_frequency *freq)
{}


/*
 * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek
 */
static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
		const struct v4l2_hw_freq_seek *seek)
{}

/*
 * si470x_vidioc_enum_freq_bands - enumerate supported bands
 */
static int si470x_vidioc_enum_freq_bands(struct file *file, void *priv,
					 struct v4l2_frequency_band *band)
{}

const struct v4l2_ctrl_ops si470x_ctrl_ops =;
EXPORT_SYMBOL_GPL();

static int si470x_vidioc_querycap(struct file *file, void *priv,
		struct v4l2_capability *capability)
{
	struct si470x_device *radio = video_drvdata(file);

	return radio->vidioc_querycap(file, priv, capability);
};

/*
 * si470x_ioctl_ops - video device ioctl operations
 */
static const struct v4l2_ioctl_ops si470x_ioctl_ops =;


/*
 * si470x_viddev_template - video device interface
 */
const struct video_device si470x_viddev_template =;
EXPORT_SYMBOL_GPL();

MODULE_DESCRIPTION();
MODULE_LICENSE();