media updates for v4.5-rc1

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJWk6q+AAoJEAhfPr2O5OEVgPQP/jpiR/EmVbTBMByEYoeJbruJ
 jFGb4ui3PyrLZVlt3gTCRbm9wQ9CZM061Ih2xFCMtmG5geU3fYV6Zu+Sz+32aqIX
 H/M6u8l/usVPsQyLaOAllF0xOrCivz4SQbgn7wjPJswu5lziNKnAH0PTkiZ5/637
 UPI+r5g1zjHWXcx4zI265+yrlsOibDVrrZ0N44RJ6IHvxZr5PJyleQzyCoHnE9/S
 5Bz23MpEUwFzOTmr0zdWviTRvYDBJVnVt1hKHpeOh4Gexv94A+taMrgR/Zqx/xR+
 0Q6HUbtKSPe5V+fjMMGgKgYIz/DlwmCdPzt1FikoVwNFRDFyJmMis4gA4gnaHWsw
 4gMRKnwntXTSIo6b8oIZ50KJeY5W2tzy+/DlcG6tE5r5vOLTr4m/WfX+DGkeZT1i
 kOx411sssDCefNgZGSothtWCGL1rvGkB1yiqn8iLhW73e0BMOqOGzXYgp5WsMcix
 XoXpT3Fm5NyAcNM7ki6jnmIyO8M/nWUErc0V25t126dNgdM7pWdiCUoOcsK+g0Md
 XJzu0qmPRMXVX8fP1jTkL2oQMlKZctsLk509zc81DCcJPrLIT9LrfiaM+Dqsch4d
 qLgDRn3wErkSNU5HBAhusJrfFKUMfgLgDFlRnEcvfkOXUlATJAndEQFNnQ3x+z8b
 eISNNUDzM8Z/AxCpl0xB
 =PA5/
 -----END PGP SIGNATURE-----

Merge tag 'media/v4.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media updates from Mauro Carvalho Chehab:
 "The part of patches for Kernel 4.5.  There's nothing really big here:

   - driver-specific headers for media devices were moved to separate
     directories, in order to make clear what headers belong to the core
     kABI and require documentation

   - Platform data for media drivers were moved from include/media to
     include/linux/platform_data/media

   - add a driver for cs3308 8-channel volume control, used on some
     high-end capture boards

   - lirc.h kAPI header were added at include/uapi/linux

   - Driver cleanups, new board additions and improvements"

* tag 'media/v4.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (204 commits)
  [media] rc: sunxi-cir: Initialize the spinlock properly
  [media] rtl2832: do not filter out slave TS null packets
  [media] rtl2832: print reg number on error case
  [media] rtl28xxu: return demod reg page from driver cache
  [media] coda: enable MPEG-2 ES decoding
  [media] coda: don't start streaming without queued buffers
  [media] coda: hook up vidioc_prepare_buf
  [media] coda: relax coda_jpeg_check_buffer for trailing bytes
  [media] coda: make to_coda_video_device static
  [media] s5p-mfc: remove volatile attribute from MFC register addresses
  [media] s5p-mfc: merge together s5p_mfc_hw_call and s5p_mfc_hw_call_void
  [media] s5p-mfc: use spinlock to protect MFC context
  [media] s5p-mfc: remove unnecessary callbacks
  [media] s5p-mfc: make queue cleanup code common
  [media] s5p-mfc: use one implementation of s5p_mfc_get_new_ctx
  [media] s5p-mfc: constify s5p_mfc_codec_ops structures
  [media] au8522: Avoid memory leak for device config data
  [media] ir-lirc-codec.c: don't leak lirc->drv-rbuf
  [media] uvcvideo: small cleanup in uvc_video_clock_update()
  [media] uvcvideo: Fix reading the current exposure value of UVC
  ...
This commit is contained in:
Linus Torvalds 2016-01-11 22:17:44 -08:00
commit 47c62e4be7
528 changed files with 4540 additions and 4096 deletions

View file

@ -9,7 +9,7 @@ menuconfig MEDIA_SUPPORT
If you want to use Webcams, Video grabber devices and/or TV devices
enable this option and other options below.
Additional info and docs are available on the web at
<http://linuxtv.org>
<https://linuxtv.org>
if MEDIA_SUPPORT
@ -51,7 +51,7 @@ config MEDIA_RADIO_SUPPORT
Enable AM/FM radio support.
Additional info and docs are available on the web at
<http://linuxtv.org>
<https://linuxtv.org>
Say Y when you have a board with radio support.

View file

@ -27,7 +27,7 @@
#include <linux/videodev2.h>
#include <media/tuner.h>
#include <media/cx2341x.h>
#include <media/drv-intf/cx2341x.h>
#include <media/v4l2-common.h>
MODULE_DESCRIPTION("cx23415/6/8 driver");

View file

@ -20,7 +20,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/saa7146.h>
#include <media/drv-intf/saa7146.h>
#include <linux/module.h>
static int saa7146_num;

View file

@ -1,6 +1,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/saa7146_vv.h>
#include <media/drv-intf/saa7146_vv.h>
#include <linux/module.h>
/****************************************************************************/

View file

@ -2,7 +2,7 @@
#include <linux/kernel.h>
#include <linux/export.h>
#include <media/saa7146_vv.h>
#include <media/drv-intf/saa7146_vv.h>
static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
{

View file

@ -1,6 +1,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/saa7146_vv.h>
#include <media/drv-intf/saa7146_vv.h>
static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
{

View file

@ -1,4 +1,4 @@
#include <media/saa7146_vv.h>
#include <media/drv-intf/saa7146_vv.h>
static int vbi_pixel_to_capture = 720 * 2;

View file

@ -1,6 +1,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/saa7146_vv.h>
#include <media/drv-intf/saa7146_vv.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <linux/module.h>

View file

@ -30,8 +30,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/input.h>
#include <media/rc-core.h>
#define IR_DEFAULT_TIMEOUT 100
struct smscore_device_t;
struct ir_t {

View file

@ -32,6 +32,49 @@
#include <linux/time.h>
#include <linux/dvb/dmx.h>
/**
* DOC: Digital TV Demux
*
* The Kernel Digital TV Demux kABI defines a driver-internal interface for
* registering low-level, hardware specific driver to a hardware independent
* demux layer. It is only of interest for Digital TV device driver writers.
* The header file for this kABI is named demux.h and located in
* drivers/media/dvb-core.
*
* The demux kABI should be implemented for each demux in the system. It is
* used to select the TS source of a demux and to manage the demux resources.
* When the demux client allocates a resource via the demux kABI, it receives
* a pointer to the kABI of that resource.
*
* Each demux receives its TS input from a DVB front-end or from memory, as
* set via this demux kABI. In a system with more than one front-end, the kABI
* can be used to select one of the DVB front-ends as a TS source for a demux,
* unless this is fixed in the HW platform.
*
* The demux kABI only controls front-ends regarding to their connections with
* demuxes; the kABI used to set the other front-end parameters, such as
* tuning, are devined via the Digital TV Frontend kABI.
*
* The functions that implement the abstract interface demux should be defined
* static or module private and registered to the Demux core for external
* access. It is not necessary to implement every function in the struct
* &dmx_demux. For example, a demux interface might support Section filtering,
* but not PES filtering. The kABI client is expected to check the value of any
* function pointer before calling the function: the value of NULL means
* that the function is not available.
*
* Whenever the functions of the demux API modify shared data, the
* possibilities of lost update and race condition problems should be
* addressed, e.g. by protecting parts of code with mutexes.
*
* Note that functions called from a bottom half context must not sleep.
* Even a simple memory allocation without using %GFP_ATOMIC can result in a
* kernel thread being put to sleep if swapping is needed. For example, the
* Linux Kernel calls the functions of a network device interface from a
* bottom half context. Thus, if a demux kABI function is called from network
* device code, the function must not sleep.
*/
/*
* Common definitions
*/
@ -187,8 +230,28 @@ struct dmx_section_feed {
int (*stop_filtering)(struct dmx_section_feed *feed);
};
/*
* Callback functions
/**
* DOC: Demux Callback
*
* This kernel-space API comprises the callback functions that deliver filtered
* data to the demux client. Unlike the other DVB kABIs, these functions are
* provided by the client and called from the demux code.
*
* The function pointers of this abstract interface are not packed into a
* structure as in the other demux APIs, because the callback functions are
* registered and used independent of each other. As an example, it is possible
* for the API client to provide several callback functions for receiving TS
* packets and no callbacks for PES packets or sections.
*
* The functions that implement the callback API need not be re-entrant: when
* a demux driver calls one of these functions, the driver is not allowed to
* call the function again before the original call returns. If a callback is
* triggered by a hardware interrupt, it is recommended to use the Linux
* bottom half mechanism or start a tasklet instead of making the callback
* function call directly from a hardware interrupt.
*
* This mechanism is implemented by dmx_ts_cb() and dmx_section_cb()
* callbacks.
*/
/**

View file

@ -389,4 +389,5 @@
#define USB_PID_PCTV_2002E_SE 0x025d
#define USB_PID_SVEON_STV27 0xd3af
#define USB_PID_TURBOX_DTT_2000 0xd3a4
#define USB_PID_WINTV_SOLOHD 0x0264
#endif

View file

@ -891,21 +891,21 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
}
/*
* Sleep until gettimeofday() > waketime + add_usec
* This needs to be as precise as possible, but as the delay is
* usually between 2ms and 32ms, it is done using a scheduled msleep
* followed by usleep (normally a busy-wait loop) for the remainder
* Sleep for the amount of time given by add_usec parameter
*
* This needs to be as precise as possible, as it affects the detection of
* the dish tone command at the satellite subsystem. The precision is improved
* by using a scheduled msleep followed by udelay for the remainder.
*/
void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec)
{
s32 delta, newdelta;
s32 delta;
ktime_add_us(*waketime, add_usec);
*waketime = ktime_add_us(*waketime, add_usec);
delta = ktime_us_delta(ktime_get_real(), *waketime);
if (delta > 2500) {
msleep((delta - 1500) / 1000);
newdelta = ktime_us_delta(ktime_get_real(), *waketime);
delta = (newdelta > delta) ? 0 : newdelta;
delta = ktime_us_delta(ktime_get_real(), *waketime);
}
if (delta > 0)
udelay(delta);
@ -2313,9 +2313,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
dev_dbg(fe->dvb->device, "%s: current delivery system on cache: %d, V3 type: %d\n",
__func__, c->delivery_system, fe->ops.info.type);
/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
* do it, it is done for it. */
info->caps |= FE_CAN_INVERSION_AUTO;
/* Set CAN_INVERSION_AUTO bit on in other than oneshot mode */
if (!(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT))
info->caps |= FE_CAN_INVERSION_AUTO;
err = 0;
break;
}
@ -2710,6 +2710,11 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
else if (fe->ops.tuner_ops.init)
ret = fe->ops.tuner_ops.init(fe);
if (fe->ops.set_tone && fepriv->tone != -1)
fe->ops.set_tone(fe, fepriv->tone);
if (fe->ops.set_voltage && fepriv->voltage != -1)
fe->ops.set_voltage(fe, fepriv->voltage);
fe->exit = DVB_FE_NO_EXIT;
fepriv->state = FESTATE_RETUNE;
dvb_frontend_wakeup(fe);

View file

@ -42,6 +42,29 @@
#include "dvbdev.h"
/**
* DOC: Digital TV Frontend
*
* The Digital TV Frontend kABI defines a driver-internal interface for
* registering low-level, hardware specific driver to a hardware independent
* frontend layer. It is only of interest for Digital TV device driver writers.
* The header file for this API is named dvb_frontend.h and located in
* drivers/media/dvb-core.
*
* Before using the Digital TV frontend core, the bridge driver should attach
* the frontend demod, tuner and SEC devices and call dvb_register_frontend(),
* in order to register the new frontend at the subsystem. At device
* detach/removal, the bridge driver should call dvb_unregister_frontend() to
* remove the frontend from the core and then dvb_frontend_detach() to free the
* memory allocated by the frontend drivers.
*
* The drivers should also call dvb_frontend_suspend() as part of their
* handler for the &device_driver.suspend(), and dvb_frontend_resume() as
* part of their handler for &device_driver.resume().
*
* A few other optional functions are provided to handle some special cases.
*/
/*
* Maximum number of Delivery systems per frontend. It
* should be smaller or equal to 32
@ -112,16 +135,6 @@ struct analog_parameters {
u64 std;
};
enum tuner_param {
DVBFE_TUNER_FREQUENCY = (1 << 0),
DVBFE_TUNER_TUNERSTEP = (1 << 1),
DVBFE_TUNER_IFFREQ = (1 << 2),
DVBFE_TUNER_BANDWIDTH = (1 << 3),
DVBFE_TUNER_REFCLOCK = (1 << 4),
DVBFE_TUNER_IQSENSE = (1 << 5),
DVBFE_TUNER_DUMMY = (1 << 31)
};
/**
* enum dvbfe_algo - defines the algorithm used to tune into a channel
*
@ -152,15 +165,6 @@ enum dvbfe_algo {
DVBFE_ALGO_RECOVERY = (1 << 31)
};
struct tuner_state {
u32 frequency;
u32 tunerstep;
u32 ifreq;
u32 bandwidth;
u32 iqsense;
u32 refclock;
};
/**
* enum dvbfe_search - search callback possible return status
*
@ -209,12 +213,12 @@ enum dvbfe_search {
* are stored at @dvb_frontend.dtv_property_cache;. The
* tuner demod can change the parameters to reflect the
* changes needed for the channel to be tuned, and
* update statistics.
* update statistics. This is the recommended way to set
* the tuner parameters and should be used on newer
* drivers.
* @set_analog_params: callback function used to tune into an analog TV
* channel on hybrid tuners. It passes @analog_parameters;
* to the driver.
* @calc_regs: callback function used to pass register data settings
* for simple tuners.
* @set_config: callback function used to send some tuner-specific
* parameters.
* @get_frequency: get the actual tuned frequency
@ -227,16 +231,10 @@ enum dvbfe_search {
* via DVBv5 API (@dvb_frontend.dtv_property_cache;).
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @set_frequency: Set a new frequency. Please notice that using
* set_params is preferred.
* @set_bandwidth: Set a new frequency. Please notice that using
* set_params is preferred.
* @set_state: callback function used on some legacy drivers that
* don't implement set_params in order to set properties.
* Shouldn't be used on new drivers.
* @get_state: callback function used to get properties by some
* legacy drivers that don't implement set_params.
* Shouldn't be used on new drivers.
* @calc_regs: callback function used to pass register data settings
* for simple tuners. Shouldn't be used on newer drivers.
* @set_frequency: Set a new frequency. Shouldn't be used on newer drivers.
* @set_bandwidth: Set a new frequency. Shouldn't be used on newer drivers.
*
* NOTE: frequencies used on get_frequency and set_frequency are in Hz for
* terrestrial/cable or kHz for satellite.
@ -252,14 +250,10 @@ struct dvb_tuner_ops {
int (*suspend)(struct dvb_frontend *fe);
int (*resume)(struct dvb_frontend *fe);
/** This is for simple PLLs - set all parameters in one go. */
/* This is the recomended way to set the tuner */
int (*set_params)(struct dvb_frontend *fe);
int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
/** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
int (*calc_regs)(struct dvb_frontend *fe, u8 *buf, int buf_len);
/** This is to allow setting tuner-specific configs */
int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
@ -272,17 +266,23 @@ struct dvb_tuner_ops {
int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
/** These are provided separately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter separately. */
int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
/*
* This is support for demods like the mt352 - fills out the supplied
* buffer with what to write.
*
* Don't use on newer drivers.
*/
int (*calc_regs)(struct dvb_frontend *fe, u8 *buf, int buf_len);
/*
* These are provided separately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter separately.
* These are provided separately from set_params in order to
* facilitate silicon tuners which require sophisticated tuning loops,
* controlling each parameter separately.
*
* Don't use on newer drivers.
*/
int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
};
/**
@ -404,6 +404,11 @@ struct dtv_frontend_properties;
* FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite).
* @dishnetwork_send_legacy_command: callback function to implement the
* FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite).
* Drivers should not use this, except when the DVB
* core emulation fails to provide proper support (e.g.
* if set_voltage() takes more than 8ms to work), and
* when backward compatibility with this legacy API is
* required.
* @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C
* mux support instead.
* @ts_bus_ctrl: callback function used to take control of the TS bus.
@ -466,7 +471,8 @@ struct dvb_frontend_ops {
int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
int (*set_lna)(struct dvb_frontend *);
/* These callbacks are for devices that implement their own
/*
* These callbacks are for devices that implement their own
* tuning algorithms, rather than a simple swzigzag
*/
enum dvbfe_search (*search)(struct dvb_frontend *fe);
@ -682,17 +688,126 @@ struct dvb_frontend {
unsigned int exit;
};
extern int dvb_register_frontend(struct dvb_adapter *dvb,
/**
* dvb_register_frontend() - Registers a DVB frontend at the adapter
*
* @dvb: pointer to the dvb adapter
* @fe: pointer to the frontend struct
*
* Allocate and initialize the private data needed by the frontend core to
* manage the frontend and calls dvb_register_device() to register a new
* frontend. It also cleans the property cache that stores the frontend
* parameters and selects the first available delivery system.
*/
int dvb_register_frontend(struct dvb_adapter *dvb,
struct dvb_frontend *fe);
extern int dvb_unregister_frontend(struct dvb_frontend *fe);
/**
* dvb_unregister_frontend() - Unregisters a DVB frontend
*
* @fe: pointer to the frontend struct
*
* Stops the frontend kthread, calls dvb_unregister_device() and frees the
* private frontend data allocated by dvb_register_frontend().
*
* NOTE: This function doesn't frees the memory allocated by the demod,
* by the SEC driver and by the tuner. In order to free it, an explicit call to
* dvb_frontend_detach() is needed, after calling this function.
*/
int dvb_unregister_frontend(struct dvb_frontend *fe);
extern void dvb_frontend_detach(struct dvb_frontend *fe);
/**
* dvb_frontend_detach() - Detaches and frees frontend specific data
*
* @fe: pointer to the frontend struct
*
* This function should be called after dvb_unregister_frontend(). It
* calls the SEC, tuner and demod release functions:
* &dvb_frontend_ops.release_sec, &dvb_frontend_ops.tuner_ops.release,
* &dvb_frontend_ops.analog_ops.release and &dvb_frontend_ops.release.
*
* If the driver is compiled with CONFIG_MEDIA_ATTACH, it also decreases
* the module reference count, needed to allow userspace to remove the
* previously used DVB frontend modules.
*/
void dvb_frontend_detach(struct dvb_frontend *fe);
extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
extern int dvb_frontend_suspend(struct dvb_frontend *fe);
extern int dvb_frontend_resume(struct dvb_frontend *fe);
/**
* dvb_frontend_suspend() - Suspends a Digital TV frontend
*
* @fe: pointer to the frontend struct
*
* This function prepares a Digital TV frontend to suspend.
*
* In order to prepare the tuner to suspend, if
* &dvb_frontend_ops.tuner_ops.suspend() is available, it calls it. Otherwise,
* it will call &dvb_frontend_ops.tuner_ops.sleep(), if available.
*
* It will also call &dvb_frontend_ops.sleep() to put the demod to suspend.
*
* The drivers should also call dvb_frontend_suspend() as part of their
* handler for the &device_driver.suspend().
*/
int dvb_frontend_suspend(struct dvb_frontend *fe);
extern void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec);
/**
* dvb_frontend_resume() - Resumes a Digital TV frontend
*
* @fe: pointer to the frontend struct
*
* This function resumes the usual operation of the tuner after resume.
*
* In order to resume the frontend, it calls the demod &dvb_frontend_ops.init().
*
* If &dvb_frontend_ops.tuner_ops.resume() is available, It, it calls it.
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init(), if available.
*
* Once tuner and demods are resumed, it will enforce that the SEC voltage and
* tone are restored to their previous values and wake up the frontend's
* kthread in order to retune the frontend.
*
* The drivers should also call dvb_frontend_resume() as part of their
* handler for the &device_driver.resume().
*/
int dvb_frontend_resume(struct dvb_frontend *fe);
/**
* dvb_frontend_reinitialise() - forces a reinitialisation at the frontend
*
* @fe: pointer to the frontend struct
*
* Calls &dvb_frontend_ops.init() and &dvb_frontend_ops.tuner_ops.init(),
* and resets SEC tone and voltage (for Satellite systems).
*
* NOTE: Currently, this function is used only by one driver (budget-av).
* It seems to be due to address some special issue with that specific
* frontend.
*/
void dvb_frontend_reinitialise(struct dvb_frontend *fe);
/**
* dvb_frontend_sleep_until() - Sleep for the amount of time given by
* add_usec parameter
*
* @waketime: pointer to a struct ktime_t
* @add_usec: time to sleep, in microseconds
*
* This function is used to measure the time required for the
* %FE_DISHNETWORK_SEND_LEGACY_CMD ioctl to work. It needs to be as precise
* as possible, as it affects the detection of the dish tone command at the
* satellite subsystem.
*
* Its used internally by the DVB frontend core, in order to emulate
* %FE_DISHNETWORK_SEND_LEGACY_CMD using the &dvb_frontend_ops.set_voltage()
* callback.
*
* NOTE: it should not be used at the drivers, as the emulation for the
* legacy callback is provided by the Kernel. The only situation where this
* should be at the drivers is when there are some bugs at the hardware that
* would prevent the core emulation to work. On such cases, the driver would
* be writing a &dvb_frontend_ops.dishnetwork_send_legacy_command() and
* calling this function directly.
*/
void dvb_frontend_sleep_until(ktime_t *waketime, u32 add_usec);
#endif

View file

@ -264,7 +264,7 @@ config DVB_MB86A16
config DVB_TDA10071
tristate "NXP TDA10071"
depends on DVB_CORE && I2C
select REGMAP
select REGMAP_I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.

View file

@ -44,7 +44,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
int ret;
u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
struct i2c_msg msg = { .addr = state->config->demod_address,
struct i2c_msg msg = { .addr = state->config.demod_address,
.flags = 0, .buf = buf, .len = 3 };
ret = i2c_transfer(state->i2c, &msg, 1);
@ -64,9 +64,9 @@ u8 au8522_readreg(struct au8522_state *state, u16 reg)
u8 b1[] = { 0 };
struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, .flags = 0,
{ .addr = state->config.demod_address, .flags = 0,
.buf = b0, .len = 2 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD,
{ .addr = state->config.demod_address, .flags = I2C_M_RD,
.buf = b1, .len = 1 } };
ret = i2c_transfer(state->i2c, msg, 2);
@ -140,7 +140,7 @@ EXPORT_SYMBOL(au8522_release_state);
static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
{
struct au8522_led_config *led_config = state->config->led_cfg;
struct au8522_led_config *led_config = state->config.led_cfg;
u8 val;
/* bail out if we can't control an LED */
@ -170,7 +170,7 @@ static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
*/
int au8522_led_ctrl(struct au8522_state *state, int led)
{
struct au8522_led_config *led_config = state->config->led_cfg;
struct au8522_led_config *led_config = state->config.led_cfg;
int i, ret = 0;
/* bail out if we can't control an LED */

View file

@ -730,7 +730,6 @@ static int au8522_probe(struct i2c_client *client,
struct v4l2_ctrl_handler *hdl;
struct v4l2_subdev *sd;
int instance;
struct au8522_config *demod_config;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter,
@ -754,15 +753,7 @@ static int au8522_probe(struct i2c_client *client,
break;
}
demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
if (demod_config == NULL) {
if (instance == 1)
kfree(state);
return -ENOMEM;
}
demod_config->demod_address = 0x8e >> 1;
state->config = demod_config;
state->config.demod_address = 0x8e >> 1;
state->i2c = client->adapter;
sd = &state->sd;
@ -784,8 +775,7 @@ static int au8522_probe(struct i2c_client *client,
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
kfree(demod_config);
kfree(state);
au8522_release_state(state);
return err;
}

View file

@ -566,7 +566,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_writereg(state,
VSB_mod_tab[i].reg,
VSB_mod_tab[i].data);
au8522_set_if(fe, state->config->vsb_if);
au8522_set_if(fe, state->config.vsb_if);
break;
case QAM_64:
dprintk("%s() QAM 64\n", __func__);
@ -574,7 +574,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_writereg(state,
QAM64_mod_tab[i].reg,
QAM64_mod_tab[i].data);
au8522_set_if(fe, state->config->qam_if);
au8522_set_if(fe, state->config.qam_if);
break;
case QAM_256:
if (zv_mode) {
@ -583,7 +583,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_writereg(state,
QAM256_mod_tab_zv_mode[i].reg,
QAM256_mod_tab_zv_mode[i].data);
au8522_set_if(fe, state->config->qam_if);
au8522_set_if(fe, state->config.qam_if);
msleep(100);
au8522_writereg(state, 0x821a, 0x00);
} else {
@ -592,7 +592,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe,
au8522_writereg(state,
QAM256_mod_tab[i].reg,
QAM256_mod_tab[i].data);
au8522_set_if(fe, state->config->qam_if);
au8522_set_if(fe, state->config.qam_if);
}
break;
default:
@ -666,7 +666,7 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
*status |= FE_HAS_LOCK | FE_HAS_SYNC;
}
switch (state->config->status_mode) {
switch (state->config.status_mode) {
case AU8522_DEMODLOCKING:
dprintk("%s() DEMODLOCKING\n", __func__);
if (*status & FE_HAS_VITERBI)
@ -704,7 +704,7 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status)
static int au8522_led_status(struct au8522_state *state, const u16 *snr)
{
struct au8522_led_config *led_config = state->config->led_cfg;
struct au8522_led_config *led_config = state->config.led_cfg;
int led;
u16 strong;
@ -758,7 +758,7 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
au8522_readreg(state, 0x4311),
snr);
if (state->config->led_cfg)
if (state->config.led_cfg)
au8522_led_status(state, snr);
return ret;
@ -866,7 +866,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
}
/* setup the state */
state->config = config;
state->config = *config;
state->i2c = i2c;
state->operational_mode = AU8522_DIGITAL_MODE;

View file

@ -50,7 +50,7 @@ struct au8522_state {
struct list_head hybrid_tuner_instance_list;
/* configuration settings */
const struct au8522_config *config;
struct au8522_config config;
struct dvb_frontend frontend;

View file

@ -21,7 +21,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef BSBE1_D01A_H

View file

@ -19,7 +19,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef BSBE1_H

View file

@ -19,7 +19,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef BSRU6_H

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#include <linux/delay.h>
#include <linux/errno.h>

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef _ISL6405_H

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#include <linux/delay.h>
#include <linux/errno.h>

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef _ISL6421_H

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#include <linux/delay.h>
#include <linux/errno.h>

View file

@ -21,7 +21,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef _LNBP21_H

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#include <linux/delay.h>
#include <linux/errno.h>

View file

@ -22,7 +22,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* the project's page is at http://www.linuxtv.org
* the project's page is at https://linuxtv.org
*/
#ifndef _LNBP22_H

View file

@ -976,7 +976,8 @@ static int rtl2832_regmap_read(void *context, const void *reg_buf,
ret = __i2c_transfer(client->adapter, msg, 2);
if (ret != 2) {
dev_warn(&client->dev, "i2c reg read failed %d\n", ret);
dev_warn(&client->dev, "i2c reg read failed %d reg %02x\n",
ret, *(u8 *)reg_buf);
if (ret >= 0)
ret = -EREMOTEIO;
return ret;
@ -999,7 +1000,8 @@ static int rtl2832_regmap_write(void *context, const void *data, size_t count)
ret = __i2c_transfer(client->adapter, msg, 1);
if (ret != 1) {
dev_warn(&client->dev, "i2c reg write failed %d\n", ret);
dev_warn(&client->dev, "i2c reg write failed %d reg %02x\n",
ret, *(u8 *)data);
if (ret >= 0)
ret = -EREMOTEIO;
return ret;
@ -1028,7 +1030,8 @@ static int rtl2832_regmap_gather_write(void *context, const void *reg,
ret = __i2c_transfer(client->adapter, msg, 1);
if (ret != 1) {
dev_warn(&client->dev, "i2c reg write failed %d\n", ret);
dev_warn(&client->dev, "i2c reg write failed %d reg %02x\n",
ret, *(u8 const *)reg);
if (ret >= 0)
ret = -EREMOTEIO;
return ret;
@ -1097,18 +1100,6 @@ static int rtl2832_enable_slave_ts(struct i2c_client *client)
if (ret)
goto err;
ret = rtl2832_bulk_write(client, 0x022, "\x01", 1);
if (ret)
goto err;
ret = rtl2832_bulk_write(client, 0x026, "\x1f", 1);
if (ret)
goto err;
ret = rtl2832_bulk_write(client, 0x027, "\xff", 1);
if (ret)
goto err;
ret = rtl2832_bulk_write(client, 0x192, "\x7f\xf7\xff", 3);
if (ret)
goto err;

View file

@ -310,7 +310,7 @@ static void rtl2832_sdr_urb_complete(struct urb *urb)
len = rtl2832_sdr_convert_stream(dev, ptr, urb->transfer_buffer,
urb->actual_length);
vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len);
v4l2_get_timestamp(&fbuf->vb.timestamp);
fbuf->vb.vb2_buf.timestamp = ktime_get_ns();
fbuf->vb.sequence = dev->sequence++;
vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE);
}
@ -490,7 +490,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh,
/* Videobuf2 operations */
static int rtl2832_sdr_queue_setup(struct vb2_queue *vq,
const void *parg, unsigned int *nbuffers,
unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
{
struct rtl2832_sdr_dev *dev = vb2_get_drv_priv(vq);

View file

@ -1,21 +1,21 @@
/*
Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
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 program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
References:
http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
*/
* Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
*
* Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* References:
* http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
*/
#include <linux/delay.h>
#include <linux/errno.h>
@ -31,16 +31,18 @@
#include "si2165_priv.h"
#include "si2165.h"
/* Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx
* uses 16 MHz xtal */
/* Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx
* uses 24 MHz clock provided by tuner */
/*
* Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx
* uses 16 MHz xtal
*
* Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx
* uses 24 MHz clock provided by tuner
*/
struct si2165_state {
struct i2c_adapter *i2c;
struct dvb_frontend frontend;
struct dvb_frontend fe;
struct si2165_config config;
@ -241,6 +243,27 @@ err:
return ret;
}
#define REG16(reg, val) { (reg), (val) & 0xff }, { (reg)+1, (val)>>8 & 0xff }
struct si2165_reg_value_pair {
u16 reg;
u8 val;
};
static int si2165_write_reg_list(struct si2165_state *state,
const struct si2165_reg_value_pair *regs,
int count)
{
int i;
int ret;
for (i = 0; i < count; i++) {
ret = si2165_writereg8(state, regs[i].reg, regs[i].val);
if (ret < 0)
return ret;
}
return 0;
}
static int si2165_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *s)
{
@ -258,8 +281,10 @@ static int si2165_init_pll(struct si2165_state *state)
u8 divl = 12;
u8 buf[4];
/* hardcoded values can be deleted if calculation is verified
* or it yields the same values as the windows driver */
/*
* hardcoded values can be deleted if calculation is verified
* or it yields the same values as the windows driver
*/
switch (ref_freq_Hz) {
case 16000000u:
divn = 56;
@ -274,8 +299,10 @@ static int si2165_init_pll(struct si2165_state *state)
if (ref_freq_Hz > 16000000u)
divr = 2;
/* now select divn and divp such that
* fvco is in 1624..1824 MHz */
/*
* now select divn and divp such that
* fvco is in 1624..1824 MHz
*/
if (1624000000u * divr > ref_freq_Hz * 2u * 63u)
divp = 4;
@ -341,10 +368,12 @@ static int si2165_upload_firmware_block(struct si2165_state *state,
if (len % 4 != 0)
return -EINVAL;
deb_fw_load("si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n",
deb_fw_load(
"si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n",
len, offset, block_count);
while (offset+12 <= len && cur_block < block_count) {
deb_fw_load("si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
deb_fw_load(
"si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
len, offset, cur_block, block_count);
wordcount = data[offset];
if (wordcount < 1 || data[offset+1] ||
@ -383,7 +412,8 @@ static int si2165_upload_firmware_block(struct si2165_state *state,
cur_block++;
}
deb_fw_load("si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
deb_fw_load(
"si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
len, offset, cur_block, block_count);
if (poffset)
@ -633,7 +663,7 @@ static int si2165_init(struct dvb_frontend *fe)
goto error;
/* ber_pkt */
ret = si2165_writereg16(state, 0x0470 , 0x7530);
ret = si2165_writereg16(state, 0x0470, 0x7530);
if (ret < 0)
goto error;
@ -660,22 +690,19 @@ static int si2165_init(struct dvb_frontend *fe)
goto error;
}
/* write adc values after each reset*/
ret = si2165_writereg8(state, 0x012a, 0x46);
/* ts output config */
ret = si2165_writereg8(state, 0x04e4, 0x20);
if (ret < 0)
goto error;
ret = si2165_writereg8(state, 0x012c, 0x00);
return ret;
ret = si2165_writereg16(state, 0x04ef, 0x00fe);
if (ret < 0)
goto error;
ret = si2165_writereg8(state, 0x012e, 0x0a);
return ret;
ret = si2165_writereg24(state, 0x04f4, 0x555555);
if (ret < 0)
goto error;
ret = si2165_writereg8(state, 0x012f, 0xff);
return ret;
ret = si2165_writereg8(state, 0x04e5, 0x01);
if (ret < 0)
goto error;
ret = si2165_writereg8(state, 0x0123, 0x70);
if (ret < 0)
goto error;
return ret;
return 0;
error:
@ -733,16 +760,26 @@ static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate)
do_div(oversamp, dvb_rate);
reg_value = oversamp & 0x3fffffff;
/* oversamp, usbdump contained 0x03100000; */
dprintk("%s: Write oversamp=%#x\n", __func__, reg_value);
return si2165_writereg32(state, 0x00e4, reg_value);
}
static int si2165_set_if_freq_shift(struct si2165_state *state, u32 IF)
static int si2165_set_if_freq_shift(struct si2165_state *state)
{
struct dvb_frontend *fe = &state->fe;
u64 if_freq_shift;
s32 reg_value = 0;
u32 fe_clk = si2165_get_fe_clk(state);
u32 IF = 0;
if (!fe->ops.tuner_ops.get_if_frequency) {
dev_err(&state->i2c->dev,
"%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n",
KBUILD_MODNAME);
return -EINVAL;
}
fe->ops.tuner_ops.get_if_frequency(fe, &IF);
if_freq_shift = IF;
if_freq_shift <<= 29;
@ -758,25 +795,39 @@ static int si2165_set_if_freq_shift(struct si2165_state *state, u32 IF)
return si2165_writereg32(state, 0x00e8, reg_value);
}
static int si2165_set_parameters(struct dvb_frontend *fe)
static const struct si2165_reg_value_pair dvbt_regs[] = {
/* standard = DVB-T */
{ 0x00ec, 0x01 },
{ 0x08f8, 0x00 },
/* impulsive_noise_remover */
{ 0x031c, 0x01 },
{ 0x00cb, 0x00 },
/* agc2 */
{ 0x016e, 0x41 },
{ 0x016c, 0x0e },
{ 0x016d, 0x10 },
/* agc */
{ 0x015b, 0x03 },
{ 0x0150, 0x78 },
/* agc */
{ 0x01a0, 0x78 },
{ 0x01c8, 0x68 },
/* freq_sync_range */
REG16(0x030c, 0x0064),
/* gp_reg0 */
{ 0x0387, 0x00 }
};
static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
{
int ret;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct si2165_state *state = fe->demodulator_priv;
u8 val[3];
u32 IF;
u32 dvb_rate = 0;
u16 bw10k;
dprintk("%s: called\n", __func__);
if (!fe->ops.tuner_ops.get_if_frequency) {
dev_err(&state->i2c->dev,
"%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n",
KBUILD_MODNAME);
return -EINVAL;
}
if (!state->has_dvbt)
return -EINVAL;
@ -788,34 +839,10 @@ static int si2165_set_parameters(struct dvb_frontend *fe)
bw10k = 800;
}
/* standard = DVB-T */
ret = si2165_writereg8(state, 0x00ec, 0x01);
if (ret < 0)
return ret;
ret = si2165_adjust_pll_divl(state, 12);
if (ret < 0)
return ret;
fe->ops.tuner_ops.get_if_frequency(fe, &IF);
ret = si2165_set_if_freq_shift(state, IF);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x08f8, 0x00);
if (ret < 0)
return ret;
/* ts output config */
ret = si2165_writereg8(state, 0x04e4, 0x20);
if (ret < 0)
return ret;
ret = si2165_writereg16(state, 0x04ef, 0x00fe);
if (ret < 0)
return ret;
ret = si2165_writereg24(state, 0x04f4, 0x555555);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x04e5, 0x01);
if (ret < 0)
return ret;
/* bandwidth in 10KHz steps */
ret = si2165_writereg16(state, 0x0308, bw10k);
if (ret < 0)
@ -823,48 +850,115 @@ static int si2165_set_parameters(struct dvb_frontend *fe)
ret = si2165_set_oversamp(state, dvb_rate);
if (ret < 0)
return ret;
/* impulsive_noise_remover */
ret = si2165_writereg8(state, 0x031c, 0x01);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x00cb, 0x00);
ret = si2165_write_reg_list(state, dvbt_regs, ARRAY_SIZE(dvbt_regs));
if (ret < 0)
return ret;
return 0;
}
static const struct si2165_reg_value_pair dvbc_regs[] = {
/* standard = DVB-C */
{ 0x00ec, 0x05 },
{ 0x08f8, 0x00 },
/* agc2 */
ret = si2165_writereg8(state, 0x016e, 0x41);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x016c, 0x0e);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x016d, 0x10);
if (ret < 0)
return ret;
{ 0x016e, 0x50 },
{ 0x016c, 0x0e },
{ 0x016d, 0x10 },
/* agc */
ret = si2165_writereg8(state, 0x015b, 0x03);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x0150, 0x78);
if (ret < 0)
return ret;
{ 0x015b, 0x03 },
{ 0x0150, 0x68 },
/* agc */
ret = si2165_writereg8(state, 0x01a0, 0x78);
{ 0x01a0, 0x68 },
{ 0x01c8, 0x50 },
{ 0x0278, 0x0d },
{ 0x023a, 0x05 },
{ 0x0261, 0x09 },
REG16(0x0350, 0x3e80),
{ 0x02f4, 0x00 },
{ 0x00cb, 0x01 },
REG16(0x024c, 0x0000),
REG16(0x027c, 0x0000),
{ 0x0232, 0x03 },
{ 0x02f4, 0x0b },
{ 0x018b, 0x00 },
};
static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
{
struct si2165_state *state = fe->demodulator_priv;
int ret;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
const u32 dvb_rate = p->symbol_rate;
const u32 bw_hz = p->bandwidth_hz;
if (!state->has_dvbc)
return -EINVAL;
if (dvb_rate == 0)
return -EINVAL;
ret = si2165_adjust_pll_divl(state, 14);
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x01c8, 0x68);
/* Oversampling */
ret = si2165_set_oversamp(state, dvb_rate);
if (ret < 0)
return ret;
/* freq_sync_range */
ret = si2165_writereg16(state, 0x030c, 0x0064);
ret = si2165_writereg32(state, 0x00c4, bw_hz);
if (ret < 0)
return ret;
/* gp_reg0 */
ret = si2165_readreg8(state, 0x0387, val);
ret = si2165_write_reg_list(state, dvbc_regs, ARRAY_SIZE(dvbc_regs));
if (ret < 0)
return ret;
ret = si2165_writereg8(state, 0x0387, 0x00);
return 0;
}
static const struct si2165_reg_value_pair agc_rewrite[] = {
{ 0x012a, 0x46 },
{ 0x012c, 0x00 },
{ 0x012e, 0x0a },
{ 0x012f, 0xff },
{ 0x0123, 0x70 }
};
static int si2165_set_frontend(struct dvb_frontend *fe)
{
struct si2165_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
u32 delsys = p->delivery_system;
int ret;
u8 val[3];
/* initial setting of if freq shift */
ret = si2165_set_if_freq_shift(state);
if (ret < 0)
return ret;
switch (delsys) {
case SYS_DVBT:
ret = si2165_set_frontend_dvbt(fe);
if (ret < 0)
return ret;
break;
case SYS_DVBC_ANNEX_A:
ret = si2165_set_frontend_dvbc(fe);
if (ret < 0)
return ret;
break;
default:
return -EINVAL;
}
/* dsp_addr_jump */
ret = si2165_writereg32(state, 0x0348, 0xf4000000);
if (ret < 0)
@ -874,8 +968,7 @@ static int si2165_set_parameters(struct dvb_frontend *fe)
fe->ops.tuner_ops.set_params(fe);
/* recalc if_freq_shift if IF might has changed */
fe->ops.tuner_ops.get_if_frequency(fe, &IF);
ret = si2165_set_if_freq_shift(state, IF);
ret = si2165_set_if_freq_shift(state);
if (ret < 0)
return ret;
@ -886,6 +979,7 @@ static int si2165_set_parameters(struct dvb_frontend *fe)
ret = si2165_writereg8(state, 0x0341, 0x00);
if (ret < 0)
return ret;
/* reset all */
ret = si2165_writereg8(state, 0x00c0, 0x00);
if (ret < 0)
@ -894,6 +988,13 @@ static int si2165_set_parameters(struct dvb_frontend *fe)
ret = si2165_writereg32(state, 0x0384, 0x00000000);
if (ret < 0)
return ret;
/* write adc values after each reset*/
ret = si2165_write_reg_list(state, agc_rewrite,
ARRAY_SIZE(agc_rewrite));
if (ret < 0)
return ret;
/* start_synchro */
ret = si2165_writereg8(state, 0x02e0, 0x01);
if (ret < 0)
@ -917,7 +1018,12 @@ static void si2165_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops si2165_ops = {
.info = {
.name = "Silicon Labs ",
.caps = FE_CAN_FEC_1_2 |
/* For DVB-C */
.symbol_rate_min = 1000000,
.symbol_rate_max = 7200000,
/* For DVB-T */
.frequency_stepsize = 166667,
.caps = FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
@ -930,7 +1036,6 @@ static struct dvb_frontend_ops si2165_ops = {
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
@ -943,7 +1048,7 @@ static struct dvb_frontend_ops si2165_ops = {
.init = si2165_init,
.sleep = si2165_sleep,
.set_frontend = si2165_set_parameters,
.set_frontend = si2165_set_frontend,
.read_status = si2165_read_status,
.release = si2165_release,
@ -979,9 +1084,9 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
}
/* create dvb_frontend */
memcpy(&state->frontend.ops, &si2165_ops,
memcpy(&state->fe.ops, &si2165_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
state->fe.demodulator_priv = state;
/* powerup */
io_ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
@ -1033,20 +1138,22 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config,
KBUILD_MODNAME, chip_name, rev_char, state->chip_type,
state->chip_revcode);
strlcat(state->frontend.ops.info.name, chip_name,
sizeof(state->frontend.ops.info.name));
strlcat(state->fe.ops.info.name, chip_name,
sizeof(state->fe.ops.info.name));
n = 0;
if (state->has_dvbt) {
state->frontend.ops.delsys[n++] = SYS_DVBT;
strlcat(state->frontend.ops.info.name, " DVB-T",
sizeof(state->frontend.ops.info.name));
state->fe.ops.delsys[n++] = SYS_DVBT;
strlcat(state->fe.ops.info.name, " DVB-T",
sizeof(state->fe.ops.info.name));
}
if (state->has_dvbc) {
state->fe.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
strlcat(state->fe.ops.info.name, " DVB-C",
sizeof(state->fe.ops.info.name));
}
if (state->has_dvbc)
dev_warn(&state->i2c->dev, "%s: DVB-C is not yet supported.\n",
KBUILD_MODNAME);
return &state->frontend;
return &state->fe;
error:
kfree(state);

View file

@ -252,6 +252,7 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
int rc;
u8 f;
u32 bw;
struct stb6100_state *state = fe->tuner_priv;
rc = stb6100_read_reg(state, STB6100_F);
@ -259,9 +260,9 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
return rc;
f = rc & STB6100_F_F;
state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */
bw = (f + 5) * 2000; /* x2 for ZIF */
*bandwidth = state->bandwidth = state->status.bandwidth * 1000;
*bandwidth = state->bandwidth = bw * 1000;
dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth);
return 0;
}
@ -495,68 +496,28 @@ static int stb6100_sleep(struct dvb_frontend *fe)
static int stb6100_init(struct dvb_frontend *fe)
{
struct stb6100_state *state = fe->tuner_priv;
struct tuner_state *status = &state->status;
int refclk = 27000000; /* Hz */
status->tunerstep = 125000;
status->ifreq = 0;
status->refclock = 27000000; /* Hz */
status->iqsense = 1;
status->bandwidth = 36000; /* kHz */
state->bandwidth = status->bandwidth * 1000; /* Hz */
state->reference = status->refclock / 1000; /* kHz */
/*
* iqsense = 1
* tunerstep = 125000
*/
state->bandwidth = 36000000; /* Hz */
state->reference = refclk / 1000; /* kHz */
/* Set default bandwidth. Modified, PN 13-May-10 */
return 0;
}
static int stb6100_get_state(struct dvb_frontend *fe,
enum tuner_param param,
struct tuner_state *state)
static int stb6100_set_params(struct dvb_frontend *fe)
{
switch (param) {
case DVBFE_TUNER_FREQUENCY:
stb6100_get_frequency(fe, &state->frequency);
break;
case DVBFE_TUNER_TUNERSTEP:
break;
case DVBFE_TUNER_IFFREQ:
break;
case DVBFE_TUNER_BANDWIDTH:
stb6100_get_bandwidth(fe, &state->bandwidth);
break;
case DVBFE_TUNER_REFCLOCK:
break;
default:
break;
}
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
return 0;
}
if (c->frequency > 0)
stb6100_set_frequency(fe, c->frequency);
static int stb6100_set_state(struct dvb_frontend *fe,
enum tuner_param param,
struct tuner_state *state)
{
struct stb6100_state *tstate = fe->tuner_priv;
switch (param) {
case DVBFE_TUNER_FREQUENCY:
stb6100_set_frequency(fe, state->frequency);
tstate->frequency = state->frequency;
break;
case DVBFE_TUNER_TUNERSTEP:
break;
case DVBFE_TUNER_IFFREQ:
break;
case DVBFE_TUNER_BANDWIDTH:
stb6100_set_bandwidth(fe, state->bandwidth);
tstate->bandwidth = state->bandwidth;
break;
case DVBFE_TUNER_REFCLOCK:
break;
default:
break;
}
if (c->bandwidth_hz > 0)
stb6100_set_bandwidth(fe, c->bandwidth_hz);
return 0;
}
@ -572,8 +533,9 @@ static struct dvb_tuner_ops stb6100_ops = {
.init = stb6100_init,
.sleep = stb6100_sleep,
.get_status = stb6100_get_status,
.get_state = stb6100_get_state,
.set_state = stb6100_set_state,
.set_params = stb6100_set_params,
.get_frequency = stb6100_get_frequency,
.get_bandwidth = stb6100_get_bandwidth,
.release = stb6100_release
};

View file

@ -86,7 +86,6 @@ struct stb6100_state {
const struct stb6100_config *config;
struct dvb_tuner_ops ops;
struct dvb_frontend *frontend;
struct tuner_state status;
u32 frequency;
u32 srate;

View file

@ -19,20 +19,21 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
if (tuner_ops->get_state) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (tuner_ops->get_frequency) {
err = tuner_ops->get_frequency(fe, frequency);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
*frequency = t_state.frequency;
}
return 0;
}
@ -41,13 +42,16 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u32 bw = c->bandwidth_hz;
int err = 0;
t_state.frequency = frequency;
c->frequency = frequency;
c->bandwidth_hz = 0; /* Don't adjust the bandwidth */
if (tuner_ops->set_state) {
err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (tuner_ops->set_params) {
err = tuner_ops->set_params(fe);
c->bandwidth_hz = bw;
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
@ -60,16 +64,14 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
if (tuner_ops->get_state) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
if (tuner_ops->get_bandwidth) {
err = tuner_ops->get_bandwidth(fe, bandwidth);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
*bandwidth = t_state.bandwidth;
}
return 0;
}
@ -78,13 +80,16 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u32 freq = c->frequency;
int err = 0;
t_state.bandwidth = bandwidth;
c->bandwidth_hz = bandwidth;
c->frequency = 0; /* Don't adjust the frequency */
if (tuner_ops->set_state) {
err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
if (tuner_ops->set_params) {
err = tuner_ops->set_params(fe);
c->frequency = freq;
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;

View file

@ -17,27 +17,27 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
if (tuner_ops->get_state) {
if (tuner_ops->get_frequency) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
err = tuner_ops->get_frequency(fe, frequency);
if (err < 0) {
printk(KERN_ERR "%s: Invalid parameter\n", __func__);
printk("%s: Invalid parameter\n", __func__);
return err;
}
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 0);
*frequency = state.frequency;
}
return 0;
@ -47,18 +47,21 @@ static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u32 bw = c->bandwidth_hz;
int err = 0;
state.frequency = frequency;
c->frequency = frequency;
c->bandwidth_hz = 0; /* Don't adjust the bandwidth */
if (tuner_ops->set_state) {
if (tuner_ops->set_params) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
err = tuner_ops->set_params(fe);
c->bandwidth_hz = bw;
if (err < 0) {
printk(KERN_ERR "%s: Invalid parameter\n", __func__);
printk("%s: Invalid parameter\n", __func__);
return err;
}
@ -74,14 +77,13 @@ static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
int err = 0;
if (tuner_ops->get_state) {
if (tuner_ops->get_bandwidth) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
err = tuner_ops->get_bandwidth(fe, bandwidth);
if (err < 0) {
printk(KERN_ERR "%s: Invalid parameter\n", __func__);
return err;
@ -89,8 +91,6 @@ static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 0);
*bandwidth = state.bandwidth;
}
return 0;
@ -100,16 +100,19 @@ static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state state;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u32 freq = c->frequency;
int err = 0;
state.bandwidth = bandwidth;
c->bandwidth_hz = bandwidth;
c->frequency = 0; /* Don't adjust the frequency */
if (tuner_ops->set_state) {
if (tuner_ops->set_params) {
if (frontend_ops->i2c_gate_ctrl)
frontend_ops->i2c_gate_ctrl(fe, 1);
err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
err = tuner_ops->set_params(fe);
c->frequency = freq;
if (err < 0) {
printk(KERN_ERR "%s: Invalid parameter\n", __func__);
return err;

View file

@ -66,26 +66,13 @@ exit:
return err;
}
static int tda665x_get_state(struct dvb_frontend *fe,
enum tuner_param param,
struct tuner_state *tstate)
static int tda665x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct tda665x_state *state = fe->tuner_priv;
int err = 0;
switch (param) {
case DVBFE_TUNER_FREQUENCY:
tstate->frequency = state->frequency;
break;
case DVBFE_TUNER_BANDWIDTH:
break;
default:
printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
err = -EINVAL;
break;
}
*frequency = state->frequency;
return err;
return 0;
}
static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
@ -111,9 +98,8 @@ exit:
return err;
}
static int tda665x_set_state(struct dvb_frontend *fe,
enum tuner_param param,
struct tuner_state *tstate)
static int tda665x_set_frequency(struct dvb_frontend *fe,
u32 new_frequency)
{
struct tda665x_state *state = fe->tuner_priv;
const struct tda665x_config *config = state->config;
@ -121,88 +107,96 @@ static int tda665x_set_state(struct dvb_frontend *fe,
u8 buf[4];
int err = 0;
if (param & DVBFE_TUNER_FREQUENCY) {
frequency = tstate->frequency;
if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
return -EINVAL;
}
frequency += config->frequency_offst;
frequency *= config->ref_multiplier;
frequency += config->ref_divider >> 1;
frequency /= config->ref_divider;
buf[0] = (u8) ((frequency & 0x7f00) >> 8);
buf[1] = (u8) (frequency & 0x00ff) >> 0;
buf[2] = 0x80 | 0x40 | 0x02;
buf[3] = 0x00;
/* restore frequency */
frequency = tstate->frequency;
if (frequency < 153000000) {
/* VHF-L */
buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
if (frequency < 68000000)
buf[3] |= 0x40; /* 83uA */
if (frequency < 1040000000)
buf[3] |= 0x60; /* 122uA */
if (frequency < 1250000000)
buf[3] |= 0x80; /* 163uA */
else
buf[3] |= 0xa0; /* 254uA */
} else if (frequency < 438000000) {
/* VHF-H */
buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
if (frequency < 230000000)
buf[3] |= 0x40;
if (frequency < 300000000)
buf[3] |= 0x60;
else
buf[3] |= 0x80;
} else {
/* UHF */
buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
if (frequency < 470000000)
buf[3] |= 0x60;
if (frequency < 526000000)
buf[3] |= 0x80;
else
buf[3] |= 0xa0;
}
/* Set params */
err = tda665x_write(state, buf, 5);
if (err < 0)
goto exit;
/* sleep for some time */
printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
msleep(20);
/* check status */
err = tda665x_get_status(fe, &status);
if (err < 0)
goto exit;
if (status == 1) {
printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status);
state->frequency = frequency; /* cache successful state */
} else {
printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status);
}
} else {
printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
if ((new_frequency < config->frequency_max)
|| (new_frequency > config->frequency_min)) {
printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n",
__func__, new_frequency);
return -EINVAL;
}
frequency = new_frequency;
frequency += config->frequency_offst;
frequency *= config->ref_multiplier;
frequency += config->ref_divider >> 1;
frequency /= config->ref_divider;
buf[0] = (u8) ((frequency & 0x7f00) >> 8);
buf[1] = (u8) (frequency & 0x00ff) >> 0;
buf[2] = 0x80 | 0x40 | 0x02;
buf[3] = 0x00;
/* restore frequency */
frequency = new_frequency;
if (frequency < 153000000) {
/* VHF-L */
buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
if (frequency < 68000000)
buf[3] |= 0x40; /* 83uA */
if (frequency < 1040000000)
buf[3] |= 0x60; /* 122uA */
if (frequency < 1250000000)
buf[3] |= 0x80; /* 163uA */
else
buf[3] |= 0xa0; /* 254uA */
} else if (frequency < 438000000) {
/* VHF-H */
buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
if (frequency < 230000000)
buf[3] |= 0x40;
if (frequency < 300000000)
buf[3] |= 0x60;
else
buf[3] |= 0x80;
} else {
/* UHF */
buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
if (frequency < 470000000)
buf[3] |= 0x60;
if (frequency < 526000000)
buf[3] |= 0x80;
else
buf[3] |= 0xa0;
}
/* Set params */
err = tda665x_write(state, buf, 5);
if (err < 0)
goto exit;
/* sleep for some time */
printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
msleep(20);
/* check status */
err = tda665x_get_status(fe, &status);
if (err < 0)
goto exit;
if (status == 1) {
printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n",
__func__, status);
state->frequency = frequency; /* cache successful state */
} else {
printk(KERN_ERR "%s: No Phase lock: status=%d\n",
__func__, status);
}
return 0;
exit:
printk(KERN_ERR "%s: I/O Error\n", __func__);
return err;
}
static int tda665x_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
tda665x_set_frequency(fe, c->frequency);
return 0;
}
static int tda665x_release(struct dvb_frontend *fe)
{
struct tda665x_state *state = fe->tuner_priv;
@ -213,10 +207,9 @@ static int tda665x_release(struct dvb_frontend *fe)
}
static struct dvb_tuner_ops tda665x_ops = {
.set_state = tda665x_set_state,
.get_state = tda665x_get_state,
.get_status = tda665x_get_status,
.set_params = tda665x_set_params,
.get_frequency = tda665x_get_frequency,
.release = tda665x_release
};

View file

@ -83,88 +83,71 @@ static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */
static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 };
static int tda8261_get_state(struct dvb_frontend *fe,
enum tuner_param param,
struct tuner_state *tstate)
static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct tda8261_state *state = fe->tuner_priv;
int err = 0;
switch (param) {
case DVBFE_TUNER_FREQUENCY:
tstate->frequency = state->frequency;
break;
case DVBFE_TUNER_BANDWIDTH:
tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
break;
default:
pr_err("%s: Unknown parameter (param=%d)\n", __func__, param);
err = -EINVAL;
break;
}
*frequency = state->frequency;
return err;
return 0;
}
static int tda8261_set_state(struct dvb_frontend *fe,
enum tuner_param param,
struct tuner_state *tstate)
static int tda8261_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct tda8261_state *state = fe->tuner_priv;
const struct tda8261_config *config = state->config;
u32 frequency, N, status = 0;
u8 buf[4];
int err = 0;
if (param & DVBFE_TUNER_FREQUENCY) {
/**
* N = Max VCO Frequency / Channel Spacing
* Max VCO Frequency = VCO frequency + (channel spacing - 1)
* (to account for half channel spacing on either side)
*/
frequency = tstate->frequency;
if ((frequency < 950000) || (frequency > 2150000)) {
pr_warn("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
return -EINVAL;
}
N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
pr_debug("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
__func__, config->step_size, div_tab[config->step_size], N, N);
buf[0] = (N >> 8) & 0xff;
buf[1] = N & 0xff;
buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
if (frequency < 1450000)
buf[3] = 0x00;
else if (frequency < 2000000)
buf[3] = 0x40;
else if (frequency < 2150000)
buf[3] = 0x80;
/* Set params */
if ((err = tda8261_write(state, buf)) < 0) {
pr_err("%s: I/O Error\n", __func__);
return err;
}
/* sleep for some time */
pr_debug("%s: Waiting to Phase LOCK\n", __func__);
msleep(20);
/* check status */
if ((err = tda8261_get_status(fe, &status)) < 0) {
pr_err("%s: I/O Error\n", __func__);
return err;
}
if (status == 1) {
pr_debug("%s: Tuner Phase locked: status=%d\n", __func__, status);
state->frequency = frequency; /* cache successful state */
} else {
pr_debug("%s: No Phase lock: status=%d\n", __func__, status);
}
} else {
pr_err("%s: Unknown parameter (param=%d)\n", __func__, param);
/*
* N = Max VCO Frequency / Channel Spacing
* Max VCO Frequency = VCO frequency + (channel spacing - 1)
* (to account for half channel spacing on either side)
*/
frequency = c->frequency;
if ((frequency < 950000) || (frequency > 2150000)) {
pr_warn("%s: Frequency beyond limits, frequency=%d\n",
__func__, frequency);
return -EINVAL;
}
N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
pr_debug("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
__func__, config->step_size, div_tab[config->step_size], N, N);
buf[0] = (N >> 8) & 0xff;
buf[1] = N & 0xff;
buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
if (frequency < 1450000)
buf[3] = 0x00;
else if (frequency < 2000000)
buf[3] = 0x40;
else if (frequency < 2150000)
buf[3] = 0x80;
/* Set params */
err = tda8261_write(state, buf);
if (err < 0) {
pr_err("%s: I/O Error\n", __func__);
return err;
}
/* sleep for some time */
pr_debug("%s: Waiting to Phase LOCK\n", __func__);
msleep(20);
/* check status */
if ((err = tda8261_get_status(fe, &status)) < 0) {
pr_err("%s: I/O Error\n", __func__);
return err;
}
if (status == 1) {
pr_debug("%s: Tuner Phase locked: status=%d\n", __func__,
status);
state->frequency = frequency; /* cache successful state */
} else {
pr_debug("%s: No Phase lock: status=%d\n", __func__, status);
}
return 0;
}
@ -182,14 +165,13 @@ static struct dvb_tuner_ops tda8261_ops = {
.info = {
.name = "TDA8261",
// .tuner_name = NULL,
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_step = 0
},
.set_state = tda8261_set_state,
.get_state = tda8261_get_state,
.set_params = tda8261_set_params,
.get_frequency = tda8261_get_frequency,
.get_status = tda8261_get_status,
.release = tda8261_release
};
@ -210,10 +192,7 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
fe->ops.tuner_ops = tda8261_ops;
fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size];
// fe->ops.tuner_ops.tuner_name = &config->buf;
// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
// __func__, fe->ops.tuner_ops.tuner_name);
pr_info("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
return fe;

View file

@ -21,17 +21,15 @@ static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
if (tuner_ops->get_state) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (tuner_ops->get_frequency) {
err = tuner_ops->get_frequency(fe, frequency);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
pr_err("%s: Invalid parameter\n", __func__);
return err;
}
*frequency = t_state.frequency;
printk("%s: Frequency=%d\n", __func__, t_state.frequency);
pr_debug("%s: Frequency=%d\n", __func__, *frequency);
}
return 0;
}
@ -40,37 +38,24 @@ static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
int err = 0;
t_state.frequency = frequency;
if (tuner_ops->set_state) {
err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state);
if (tuner_ops->set_params) {
err = tuner_ops->set_params(fe);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
pr_err("%s: Invalid parameter\n", __func__);
return err;
}
}
printk("%s: Frequency=%d\n", __func__, t_state.frequency);
pr_debug("%s: Frequency=%d\n", __func__, c->frequency);
return 0;
}
static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
{
struct dvb_frontend_ops *frontend_ops = &fe->ops;
struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
struct tuner_state t_state;
int err = 0;
/* FIXME! need to calculate Bandwidth */
*bandwidth = 40000000;
if (tuner_ops->get_state) {
err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state);
if (err < 0) {
printk("%s: Invalid parameter\n", __func__);
return err;
}
*bandwidth = t_state.bandwidth;
printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
}
return 0;
}

View file

@ -20,7 +20,7 @@
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*
*
* The project's page is at http://www.linuxtv.org
* The project's page is at https://linuxtv.org
*/
#ifndef TDHD1_H

View file

@ -83,6 +83,16 @@ config VIDEO_MSP3400
To compile this driver as a module, choose M here: the
module will be called msp3400.
config VIDEO_CS3308
tristate "Cirrus Logic CS3308 audio ADC"
depends on VIDEO_V4L2 && I2C
---help---
Support for the Cirrus Logic CS3308 High Performance 8-Channel
Analog Volume Control
To compile this driver as a module, choose M here: the
module will be called cs3308.
config VIDEO_CS5345
tristate "Cirrus Logic CS5345 audio ADC"
depends on VIDEO_V4L2 && I2C

View file

@ -43,6 +43,7 @@ obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
obj-$(CONFIG_VIDEO_TW2804) += tw2804.o
obj-$(CONFIG_VIDEO_TW9903) += tw9903.o
obj-$(CONFIG_VIDEO_TW9906) += tw9906.o
obj-$(CONFIG_VIDEO_CS3308) += cs3308.o
obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
obj-$(CONFIG_VIDEO_M52790) += m52790.o

View file

@ -35,7 +35,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-ctrls.h>
#include <media/ad9389b.h>
#include <media/i2c/ad9389b.h>
static int debug;
module_param(debug, int, 0644);

View file

@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/gpio/consumer.h>
#include <media/adp1653.h>
#include <media/i2c/adp1653.h>
#include <media/v4l2-device.h>
#define TIMEOUT_MAX 820000

View file

@ -1112,7 +1112,7 @@ static int init_device(struct adv7180_state *state)
mutex_lock(&state->mutex);
adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES);
usleep_range(2000, 10000);
usleep_range(5000, 10000);
ret = state->chip_info->init(state);
if (ret)

View file

@ -27,7 +27,7 @@
#include <linux/types.h>
#include <linux/videodev2.h>
#include <media/adv7183.h>
#include <media/i2c/adv7183.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>

View file

@ -28,7 +28,7 @@
#include <linux/of.h>
#include <linux/of_graph.h>
#include <media/adv7343.h>
#include <media/i2c/adv7343.h>
#include <media/v4l2-async.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>

View file

@ -31,7 +31,7 @@
#include <linux/videodev2.h>
#include <linux/uaccess.h>
#include <media/adv7393.h>
#include <media/i2c/adv7393.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>

View file

@ -32,7 +32,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/adv7511.h>
#include <media/i2c/adv7511.h>
static int debug;
module_param(debug, int, 0644);
@ -1116,7 +1116,7 @@ static int adv7511_set_fmt(struct v4l2_subdev *sd,
adv7511_wr_and_or(sd, 0x55, 0x9f, y << 5);
adv7511_wr_and_or(sd, 0x56, 0x3f, c << 6);
adv7511_wr_and_or(sd, 0x57, 0x83, (ec << 4) | (q << 2));
adv7511_wr_and_or(sd, 0x59, 0x0f, yq << 4);
adv7511_wr_and_or(sd, 0x59, 0x3f, yq << 6);
adv7511_wr_and_or(sd, 0x4a, 0xff, 1);
return 0;

View file

@ -39,7 +39,7 @@
#include <linux/workqueue.h>
#include <linux/regmap.h>
#include <media/adv7604.h>
#include <media/i2c/adv7604.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
@ -905,7 +905,7 @@ static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
if (!v4l2_match_dv_timings(timings, &predef_vid_timings[i].timings,
is_digital_input(sd) ? 250000 : 1000000))
is_digital_input(sd) ? 250000 : 1000000, false))
continue;
io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) +
@ -1479,7 +1479,7 @@ static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
for (i = 0; adv76xx_timings[i].bt.width; i++) {
if (v4l2_match_dv_timings(timings, &adv76xx_timings[i],
is_digital_input(sd) ? 250000 : 1000000)) {
is_digital_input(sd) ? 250000 : 1000000, false)) {
*timings = adv76xx_timings[i];
break;
}
@ -1644,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,
if (!timings)
return -EINVAL;
if (v4l2_match_dv_timings(&state->timings, timings, 0)) {
if (v4l2_match_dv_timings(&state->timings, timings, 0, false)) {
v4l2_dbg(1, debug, sd, "%s: no change\n", __func__);
return 0;
}

View file

@ -43,7 +43,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/adv7842.h>
#include <media/i2c/adv7842.h>
static int debug;
module_param(debug, int, 0644);
@ -155,7 +155,7 @@ static bool adv7842_check_dv_timings(const struct v4l2_dv_timings *t, void *hdl)
int i;
for (i = 0; adv7842_timings_exceptions[i].bt.width; i++)
if (v4l2_match_dv_timings(t, adv7842_timings_exceptions + i, 0))
if (v4l2_match_dv_timings(t, adv7842_timings_exceptions + i, 0, false))
return false;
return true;
}
@ -1008,7 +1008,7 @@ static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
if (!v4l2_match_dv_timings(timings, &predef_vid_timings[i].timings,
is_digital_input(sd) ? 250000 : 1000000))
is_digital_input(sd) ? 250000 : 1000000, false))
continue;
/* video std */
io_write(sd, 0x00, predef_vid_timings[i].vid_std);
@ -1659,7 +1659,7 @@ static int adv7842_s_dv_timings(struct v4l2_subdev *sd,
if (state->mode == ADV7842_MODE_SDP)
return -ENODATA;
if (v4l2_match_dv_timings(&state->timings, timings, 0)) {
if (v4l2_match_dv_timings(&state->timings, timings, 0, false)) {
v4l2_dbg(1, debug, sd, "%s: no change\n", __func__);
return 0;
}

View file

@ -15,7 +15,7 @@
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/ak881x.h>
#include <media/i2c/ak881x.h>
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>

View file

@ -31,7 +31,7 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <media/as3645a.h>
#include <media/i2c/as3645a.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>

View file

@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/bt819.h>
#include <media/i2c/bt819.h>
MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");

138
drivers/media/i2c/cs3308.c Normal file
View file

@ -0,0 +1,138 @@
/*
* Cirrus Logic cs3308 8-Channel Analog Volume Control
*
* Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
* Copyright (C) 2012 Steven Toth <stoth@kernellabs.com>
*
* Derived from cs5345.c Copyright (C) 2007 Hans Verkuil
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
MODULE_DESCRIPTION("i2c device driver for cs3308 8-channel volume control");
MODULE_AUTHOR("Devin Heitmueller");
MODULE_LICENSE("GPL");
static inline int cs3308_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
return i2c_smbus_write_byte_data(client, reg, value);
}
static inline int cs3308_read(struct v4l2_subdev *sd, u8 reg)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
return i2c_smbus_read_byte_data(client, reg);
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cs3308_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
reg->val = cs3308_read(sd, reg->reg & 0xffff);
reg->size = 1;
return 0;
}
static int cs3308_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
{
cs3308_write(sd, reg->reg & 0xffff, reg->val & 0xff);
return 0;
}
#endif
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs3308_core_ops = {
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cs3308_g_register,
.s_register = cs3308_s_register,
#endif
};
static const struct v4l2_subdev_ops cs3308_ops = {
.core = &cs3308_core_ops,
};
/* ----------------------------------------------------------------------- */
static int cs3308_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct v4l2_subdev *sd;
unsigned i;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
if ((i2c_smbus_read_byte_data(client, 0x1c) & 0xf0) != 0xe0)
return -ENODEV;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
if (sd == NULL)
return -ENOMEM;
v4l2_i2c_subdev_init(sd, client, &cs3308_ops);
/* Set some reasonable defaults */
cs3308_write(sd, 0x0d, 0x00); /* Power up all channels */
cs3308_write(sd, 0x0e, 0x00); /* Master Power */
cs3308_write(sd, 0x0b, 0x00); /* Device Configuration */
/* Set volume for each channel */
for (i = 1; i <= 8; i++)
cs3308_write(sd, i, 0xd2);
cs3308_write(sd, 0x0a, 0x00); /* Unmute all channels */
return 0;
}
/* ----------------------------------------------------------------------- */
static int cs3308_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(sd);
return 0;
}
/* ----------------------------------------------------------------------- */
static const struct i2c_device_id cs3308_id[] = {
{ "cs3308", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, cs3308_id);
static struct i2c_driver cs3308_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cs3308",
},
.probe = cs3308_probe,
.remove = cs3308_remove,
.id_table = cs3308_id,
};
module_i2c_driver(cs3308_driver);

View file

@ -19,7 +19,7 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-common.h>
#include <media/cx25840.h>
#include <media/drv-intf/cx25840.h>
#include "cx25840-core.h"

View file

@ -45,7 +45,7 @@
#include <linux/delay.h>
#include <linux/math64.h>
#include <media/v4l2-common.h>
#include <media/cx25840.h>
#include <media/drv-intf/cx25840.h>
#include "cx25840-core.h"
@ -559,7 +559,10 @@ static void cx23885_initialize(struct i2c_client *client)
cx25840_write4(client, 0x414, 0x00107d12);
/* Chroma */
cx25840_write4(client, 0x420, 0x3d008282);
if (is_cx23888(state))
cx25840_write4(client, 0x418, 0x1d008282);
else
cx25840_write4(client, 0x420, 0x3d008282);
/*
* Aux PLL
@ -666,14 +669,17 @@ static void cx23885_initialize(struct i2c_client *client)
cx25840_write4(client, 0x404, 0x0010253e);
/* CC on - Undocumented Register */
cx25840_write(client, 0x42f, 0x66);
cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66);
/* HVR-1250 / HVR1850 DIF related */
/* Power everything up */
cx25840_write4(client, 0x130, 0x0);
/* Undocumented */
cx25840_write4(client, 0x478, 0x6628021F);
if (is_cx23888(state))
cx25840_write4(client, 0x454, 0x6628021F);
else
cx25840_write4(client, 0x478, 0x6628021F);
/* AFE_CLK_OUT_CTRL - Select the clock output source as output */
cx25840_write4(client, 0x144, 0x5);
@ -1106,31 +1112,15 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
cx25840_write4(client, 0x410, 0xffff0dbf);
cx25840_write4(client, 0x414, 0x00137d03);
/* on the 887, 0x418 is HSCALE_CTRL, on the 888 it is
CHROMA_CTRL */
if (is_cx23888(state))
cx25840_write4(client, 0x418, 0x01008080);
else
cx25840_write4(client, 0x418, 0x01000000);
cx25840_write4(client, state->vbi_regs_offset + 0x42c, 0x42600000);
cx25840_write4(client, state->vbi_regs_offset + 0x430, 0x0000039b);
cx25840_write4(client, state->vbi_regs_offset + 0x438, 0x00000000);
cx25840_write4(client, 0x41c, 0x00000000);
/* on the 887, 0x420 is CHROMA_CTRL, on the 888 it is
CRUSH_CTRL */
if (is_cx23888(state))
cx25840_write4(client, 0x420, 0x001c3e0f);
else
cx25840_write4(client, 0x420, 0x001c8282);
cx25840_write4(client, 0x42c, 0x42600000);
cx25840_write4(client, 0x430, 0x0000039b);
cx25840_write4(client, 0x438, 0x00000000);
cx25840_write4(client, 0x440, 0xF8E3E824);
cx25840_write4(client, 0x444, 0x401040dc);
cx25840_write4(client, 0x448, 0xcd3f02a0);
cx25840_write4(client, 0x44c, 0x161f1000);
cx25840_write4(client, 0x450, 0x00000802);
cx25840_write4(client, state->vbi_regs_offset + 0x440, 0xF8E3E824);
cx25840_write4(client, state->vbi_regs_offset + 0x444, 0x401040dc);
cx25840_write4(client, state->vbi_regs_offset + 0x448, 0xcd3f02a0);
cx25840_write4(client, state->vbi_regs_offset + 0x44c, 0x161f1000);
cx25840_write4(client, state->vbi_regs_offset + 0x450, 0x00000802);
cx25840_write4(client, 0x91c, 0x01000000);
cx25840_write4(client, 0x8e0, 0x03063870);
@ -1400,8 +1390,14 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd,
Vlines = fmt->height + (is_50Hz ? 4 : 7);
/*
* We keep 1 margin for the Vsrc < Vlines check since the
* cx23888 reports a Vsrc of 486 instead of 487 for the NTSC
* height. Without that margin the cx23885 fails in this
* check.
*/
if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
(Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) {
v4l_err(client, "%dx%d is not a valid size!\n",
fmt->width, fmt->height);
return -ERANGE;
@ -1426,14 +1422,20 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd,
fmt->width, fmt->height, HSC, VSC);
/* HSCALE=HSC */
cx25840_write(client, 0x418, HSC & 0xff);
cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
cx25840_write(client, 0x41a, HSC >> 16);
/* VSCALE=VSC */
cx25840_write(client, 0x41c, VSC & 0xff);
cx25840_write(client, 0x41d, VSC >> 8);
/* VS_INTRLACE=1 VFILT=filter */
cx25840_write(client, 0x41e, 0x8 | filter);
if (is_cx23888(state)) {
cx25840_write4(client, 0x434, HSC | (1 << 24));
/* VSCALE=VSC VS_INTRLACE=1 VFILT=filter */
cx25840_write4(client, 0x438, VSC | (1 << 19) | (filter << 16));
} else {
cx25840_write(client, 0x418, HSC & 0xff);
cx25840_write(client, 0x419, (HSC >> 8) & 0xff);
cx25840_write(client, 0x41a, HSC >> 16);
/* VSCALE=VSC */
cx25840_write(client, 0x41c, VSC & 0xff);
cx25840_write(client, 0x41d, VSC >> 8);
/* VS_INTRLACE=1 VFILT=filter */
cx25840_write(client, 0x41e, 0x8 | filter);
}
return 0;
}
@ -1714,26 +1716,27 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
v4l_dbg(1, cx25840_debug, client, "%s video output\n",
enable ? "enable" : "disable");
/*
* It's not clear what should be done for these devices.
* The original code used the same addresses as for the cx25840, but
* those addresses do something else entirely on the cx2388x and
* cx231xx. Since it never did anything in the first place, just do
* nothing.
*/
if (is_cx2388x(state) || is_cx231xx(state))
return 0;
if (enable) {
if (is_cx2388x(state) || is_cx231xx(state)) {
v = cx25840_read(client, 0x421) | 0x0b;
cx25840_write(client, 0x421, v);
} else {
v = cx25840_read(client, 0x115) | 0x0c;
cx25840_write(client, 0x115, v);
v = cx25840_read(client, 0x116) | 0x04;
cx25840_write(client, 0x116, v);
}
v = cx25840_read(client, 0x115) | 0x0c;
cx25840_write(client, 0x115, v);
v = cx25840_read(client, 0x116) | 0x04;
cx25840_write(client, 0x116, v);
} else {
if (is_cx2388x(state) || is_cx231xx(state)) {
v = cx25840_read(client, 0x421) & ~(0x0b);
cx25840_write(client, 0x421, v);
} else {
v = cx25840_read(client, 0x115) & ~(0x0c);
cx25840_write(client, 0x115, v);
v = cx25840_read(client, 0x116) & ~(0x04);
cx25840_write(client, 0x116, v);
}
v = cx25840_read(client, 0x115) & ~(0x0c);
cx25840_write(client, 0x115, v);
v = cx25840_read(client, 0x116) & ~(0x04);
cx25840_write(client, 0x116, v);
}
return 0;
}
@ -4974,7 +4977,7 @@ static void cx23888_std_setup(struct i2c_client *client)
cx25840_write4(client, 0x4b4, 0x20524030);
cx25840_write4(client, 0x47c, 0x010a8263);
if (std & V4L2_STD_NTSC) {
if (std & V4L2_STD_525_60) {
v4l_dbg(1, cx25840_debug, client, "%s() Selecting NTSC",
__func__);
@ -5264,6 +5267,8 @@ static int cx25840_probe(struct i2c_client *client,
state->vbi_line_offset = 8;
state->id = id;
state->rev = device_id;
state->vbi_regs_offset = id == CX23888_AV ? 0x500 - 0x424 : 0;
state->std = V4L2_STD_NTSC_M;
v4l2_ctrl_handler_init(&state->hdl, 9);
v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);

View file

@ -69,6 +69,7 @@ struct cx25840_state {
enum cx25840_model id;
u32 rev;
int is_initialized;
unsigned vbi_regs_offset;
wait_queue_head_t fw_wait; /* wake up when the fw load is finished */
struct work_struct fw_work; /* work entry for fw load */
struct cx25840_ir_state *ir_state;

View file

@ -19,7 +19,7 @@
#include <linux/i2c.h>
#include <linux/firmware.h>
#include <media/v4l2-common.h>
#include <media/cx25840.h>
#include <media/drv-intf/cx25840.h>
#include "cx25840-core.h"

View file

@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/kfifo.h>
#include <linux/module.h>
#include <media/cx25840.h>
#include <media/drv-intf/cx25840.h>
#include <media/rc-core.h>
#include "cx25840-core.h"

View file

@ -19,7 +19,7 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-common.h>
#include <media/cx25840.h>
#include <media/drv-intf/cx25840.h>
#include "cx25840-core.h"
@ -104,7 +104,8 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
if (is_pal) {
for (i = 7; i <= 23; i++) {
u8 v = cx25840_read(client, 0x424 + i - 7);
u8 v = cx25840_read(client,
state->vbi_regs_offset + 0x424 + i - 7);
svbi->service_lines[0][i] = lcr2vbi[v >> 4];
svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
@ -113,7 +114,8 @@ int cx25840_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
}
} else {
for (i = 10; i <= 21; i++) {
u8 v = cx25840_read(client, 0x424 + i - 10);
u8 v = cx25840_read(client,
state->vbi_regs_offset + 0x424 + i - 10);
svbi->service_lines[0][i] = lcr2vbi[v >> 4];
svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
@ -135,7 +137,10 @@ int cx25840_s_raw_fmt(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt)
cx25840_std_setup(client);
/* VBI Offset */
cx25840_write(client, 0x47f, vbi_offset);
if (is_cx23888(state))
cx25840_write(client, 0x54f, vbi_offset);
else
cx25840_write(client, 0x47f, vbi_offset);
cx25840_write(client, 0x404, 0x2e);
return 0;
}
@ -158,7 +163,10 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
/* Sliced VBI */
cx25840_write(client, 0x404, 0x32); /* Ancillary data */
cx25840_write(client, 0x406, 0x13);
cx25840_write(client, 0x47f, vbi_offset);
if (is_cx23888(state))
cx25840_write(client, 0x54f, vbi_offset);
else
cx25840_write(client, 0x47f, vbi_offset);
if (is_pal) {
for (i = 0; i <= 6; i++)
@ -194,17 +202,23 @@ int cx25840_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *
}
if (is_pal) {
for (x = 1, i = 0x424; i <= 0x434; i++, x++)
for (x = 1, i = state->vbi_regs_offset + 0x424;
i <= state->vbi_regs_offset + 0x434; i++, x++)
cx25840_write(client, i, lcr[6 + x]);
} else {
for (x = 1, i = 0x424; i <= 0x430; i++, x++)
for (x = 1, i = state->vbi_regs_offset + 0x424;
i <= state->vbi_regs_offset + 0x430; i++, x++)
cx25840_write(client, i, lcr[9 + x]);
for (i = 0x431; i <= 0x434; i++)
for (i = state->vbi_regs_offset + 0x431;
i <= state->vbi_regs_offset + 0x434; i++)
cx25840_write(client, i, 0);
}
cx25840_write(client, 0x43c, 0x16);
cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
cx25840_write(client, state->vbi_regs_offset + 0x43c, 0x16);
if (is_cx23888(state))
cx25840_write(client, 0x428, is_pal ? 0x2a : 0x22);
else
cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
return 0;
}

View file

@ -47,7 +47,7 @@
#include <linux/workqueue.h>
#include <media/rc-core.h>
#include <media/ir-kbd-i2c.h>
#include <media/i2c/ir-kbd-i2c.h>
/* ----------------------------------------------------------------------- */
/* insmod parameters */

View file

@ -24,7 +24,7 @@
#include <linux/mutex.h>
#include <linux/regmap.h>
#include <linux/videodev2.h>
#include <media/lm3560.h>
#include <media/i2c/lm3560.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>

View file

@ -18,7 +18,7 @@
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/videodev2.h>
#include <media/lm3646.h>
#include <media/i2c/lm3646.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>

View file

@ -27,7 +27,7 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/m52790.h>
#include <media/i2c/m52790.h>
#include <media/v4l2-device.h>
MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");

View file

@ -25,8 +25,8 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/m5mols.h>
#include <media/exynos-fimc.h>
#include <media/i2c/m5mols.h>
#include <media/drv-intf/exynos-fimc.h>
#include "m5mols.h"
#include "m5mols_reg.h"

View file

@ -25,7 +25,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/m5mols.h>
#include <media/i2c/m5mols.h>
#include "m5mols.h"
#include "m5mols_reg.h"

View file

@ -56,8 +56,8 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/msp3400.h>
#include <media/tvaudio.h>
#include <media/drv-intf/msp3400.h>
#include <media/i2c/tvaudio.h>
#include "msp3400-driver.h"
/* ---------------------------------------------------------------------- */

View file

@ -4,7 +4,7 @@
#ifndef MSP3400_DRIVER_H
#define MSP3400_DRIVER_H
#include <media/msp3400.h>
#include <media/drv-intf/msp3400.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>

View file

@ -26,7 +26,7 @@
#include <linux/freezer.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/msp3400.h>
#include <media/drv-intf/msp3400.h>
#include <linux/kthread.h>
#include <linux/suspend.h>
#include "msp3400-driver.h"

View file

@ -31,7 +31,7 @@
#include <linux/v4l2-mediabus.h>
#include <media/media-entity.h>
#include <media/mt9m032.h>
#include <media/i2c/mt9m032.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
@ -671,7 +671,7 @@ static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
static const struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
.s_ctrl = mt9m032_set_ctrl,
.try_ctrl = mt9m032_try_ctrl,
};

View file

@ -26,7 +26,7 @@
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/mt9p031.h>
#include <media/i2c/mt9p031.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@ -817,7 +817,7 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
static const struct v4l2_ctrl_ops mt9p031_ctrl_ops = {
.s_ctrl = mt9p031_s_ctrl,
};

View file

@ -21,7 +21,7 @@
#include <linux/videodev2.h>
#include <linux/v4l2-mediabus.h>
#include <media/mt9t001.h>
#include <media/i2c/mt9t001.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
@ -626,7 +626,7 @@ static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static struct v4l2_ctrl_ops mt9t001_ctrl_ops = {
static const struct v4l2_ctrl_ops mt9t001_ctrl_ops = {
.s_ctrl = mt9t001_s_ctrl,
};

View file

@ -13,7 +13,7 @@
#include <asm/div64.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/mt9v011.h>
#include <media/i2c/mt9v011.h>
MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
MODULE_AUTHOR("Mauro Carvalho Chehab");
@ -454,7 +454,7 @@ static int mt9v011_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
static const struct v4l2_ctrl_ops mt9v011_ctrl_ops = {
.s_ctrl = mt9v011_s_ctrl,
};

View file

@ -25,7 +25,7 @@
#include <linux/v4l2-mediabus.h>
#include <linux/module.h>
#include <media/mt9v032.h>
#include <media/i2c/mt9v032.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-of.h>
@ -703,7 +703,7 @@ static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
static const struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
.s_ctrl = mt9v032_s_ctrl,
};

View file

@ -18,7 +18,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <media/noon010pc30.h>
#include <media/i2c/noon010pc30.h>
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/v4l2-ctrls.h>

View file

@ -37,7 +37,7 @@
#include <linux/videodev2.h>
#include <media/media-entity.h>
#include <media/ov2659.h>
#include <media/i2c/ov2659.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
@ -1249,7 +1249,7 @@ static int ov2659_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
}
static struct v4l2_ctrl_ops ov2659_ctrl_ops = {
static const struct v4l2_ctrl_ops ov2659_ctrl_ops = {
.s_ctrl = ov2659_s_ctrl,
};

View file

@ -20,7 +20,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-image-sizes.h>
#include <media/ov7670.h>
#include <media/i2c/ov7670.h>
MODULE_AUTHOR("Jonathan Corbet <[email protected]>");
MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");

View file

@ -29,7 +29,7 @@
#include <media/v4l2-image-sizes.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/ov9650.h>
#include <media/i2c/ov9650.h>
static int debug;
module_param(debug, int, 0644);

View file

@ -34,7 +34,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/s5c73m3.h>
#include <media/i2c/s5c73m3.h>
#include <media/v4l2-of.h>
#include "s5c73m3.h"

View file

@ -32,7 +32,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/s5c73m3.h>
#include <media/i2c/s5c73m3.h>
#include "s5c73m3.h"

View file

@ -37,6 +37,7 @@ enum spi_direction {
SPI_DIR_RX,
SPI_DIR_TX
};
MODULE_DEVICE_TABLE(of, s5c73m3_spi_ids);
static int spi_xmit(struct spi_device *spi_dev, void *addr, const int len,
enum spi_direction dir)

View file

@ -23,7 +23,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include <media/s5c73m3.h>
#include <media/i2c/s5c73m3.h>
#define DRIVER_NAME "S5C73M3"

View file

@ -27,7 +27,7 @@
#include <asm/unaligned.h>
#include <media/media-entity.h>
#include <media/s5k4ecgx.h>
#include <media/i2c/s5k4ecgx.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>

View file

@ -28,7 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/s5k6aa.h>
#include <media/i2c/s5k6aa.h>
static int debug;
module_param(debug, int, 0644);

View file

@ -31,7 +31,7 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <media/saa6588.h>
#include <media/i2c/saa6588.h>
#include <media/v4l2-device.h>

View file

@ -46,7 +46,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
#include <media/saa7115.h>
#include <media/i2c/saa7115.h>
#include <asm/div64.h>
#define VRES_60HZ (480+16)

View file

@ -54,7 +54,7 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/saa7127.h>
#include <media/i2c/saa7127.h>
static int debug;
static int test_image;

View file

@ -22,7 +22,7 @@
#include <linux/mutex.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include <media/smiapp.h>
#include <media/i2c/smiapp.h>
#include "smiapp-pll.h"
#include "smiapp-reg.h"

View file

@ -15,7 +15,7 @@
#include <linux/module.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <media/drv-intf/soc_mediabus.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-ctrls.h>

View file

@ -25,7 +25,7 @@
#include <linux/v4l2-mediabus.h>
#include <linux/videodev2.h>
#include <media/mt9t112.h>
#include <media/i2c/mt9t112.h>
#include <media/soc_camera.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-common.h>

View file

@ -15,9 +15,9 @@
#include <linux/log2.h>
#include <linux/module.h>
#include <media/mt9v022.h>
#include <media/i2c/mt9v022.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <media/drv-intf/soc_mediabus.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>

View file

@ -24,7 +24,7 @@
#include <linux/v4l2-mediabus.h>
#include <linux/videodev2.h>
#include <media/ov772x.h>
#include <media/i2c/ov772x.h>
#include <media/soc_camera.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-ctrls.h>

View file

@ -15,7 +15,7 @@
#include <linux/videodev2.h>
#include <linux/module.h>
#include <media/rj54n1cb0c.h>
#include <media/i2c/rj54n1cb0c.h>
#include <media/soc_camera.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>

View file

@ -26,7 +26,7 @@
#include <linux/videodev2.h>
#include <media/soc_camera.h>
#include <media/tw9910.h>
#include <media/i2c/tw9910.h>
#include <media/v4l2-clk.h>
#include <media/v4l2-subdev.h>

View file

@ -24,7 +24,7 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-mediabus.h>
#include <media/v4l2-ctrls.h>
#include <media/sr030pc30.h>
#include <media/i2c/sr030pc30.h>
static int debug;
module_param(debug, int, 0644);

View file

@ -42,7 +42,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-of.h>
#include <media/tc358743.h>
#include <media/i2c/tc358743.h>
#include "tc358743_regs.h"
@ -862,7 +862,7 @@ static void tc358743_format_change(struct v4l2_subdev *sd)
v4l2_dbg(1, debug, sd, "%s: Format changed. No signal\n",
__func__);
} else {
if (!v4l2_match_dv_timings(&state->timings, &timings, 0))
if (!v4l2_match_dv_timings(&state->timings, &timings, 0, false))
enable_stream(sd, false);
v4l2_print_dv_timings(sd->name,
@ -1366,7 +1366,7 @@ static int tc358743_s_dv_timings(struct v4l2_subdev *sd,
v4l2_print_dv_timings(sd->name, "tc358743_s_dv_timings: ",
timings, false);
if (v4l2_match_dv_timings(&state->timings, timings, 0)) {
if (v4l2_match_dv_timings(&state->timings, timings, 0, false)) {
v4l2_dbg(1, debug, sd, "%s: no change\n", __func__);
return 0;
}

View file

@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <media/ths7303.h>
#include <media/i2c/ths7303.h>
#include <media/v4l2-device.h>
#define THS7303_CHANNEL_1 1

View file

@ -36,7 +36,7 @@
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <media/tvaudio.h>
#include <media/i2c/tvaudio.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>

View file

@ -44,7 +44,7 @@
#include <media/v4l2-mediabus.h>
#include <media/v4l2-of.h>
#include <media/v4l2-ctrls.h>
#include <media/tvp514x.h>
#include <media/i2c/tvp514x.h>
#include <media/media-entity.h>
#include "tvp514x_regs.h"

Some files were not shown because too many files have changed in this diff Show more