media updates for v4.3-rc1

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJV6ifEAAoJEAhfPr2O5OEVn5kP/i2jM1tWcmV/ZEBKGAN0jpRk
 5Y/Q+rnXvOpIJSQC3dEkweoBymVMclSgSB/wFSWCZtp5MaB8KrH4/2uc3UvolF91
 7bqXt+fCUacMbDQyaabMCR83mz9tdOJLd5sf0ABqBgXGfwh5uXmBPaYBzmcYvKcW
 4D89MFUpaFDPARTs9rdpVyr0aPRU4GcN0R3snRO9Ly+cQnyV/RxPf9NqCgnI+yPq
 +NvA9ScUBcBt62piSIGR4egcAR8boxYC+0r57340S21/JVMvsHQ3ok9b1aT8/rtd
 Yl24FkcKrRV0ShN5S1RmW5DLH/HRGabuMjkiEz9xq52FGD2sQQda0At58dWivsa4
 XYdxS9UUfb9Z+qyeMdmCl1MUFRrV2G4H6VItP+GKyT3UZLEDcLl6hBg3SkyWxWB4
 CSO5WuRThiIB86OVcIaREftzqDy5HdvH3ZKRD7QrW0DItGVjQwV5j6gvwqO9OEXs
 99BnSohyKwUBonumE2ZtFGGhIwIomllrMSqg991bPH9+13bg/rPxUqntkPrVap/9
 cV3qKO8ZFrz5UInBnR1U83l60ZK7rV4G6AVMSMKpM9XVK9TDKryAUN9Mhj5XWRH8
 hbma89TQVdhdrITtt27uzj8F622cvZvxd1BqDBR8DjKVvtv/E2GPzJrAj7GHe3/o
 NgzP5fF6X2Si32GNb7J8
 =cIed
 -----END PGP SIGNATURE-----

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

Pull media updates from Mauro Carvalho Chehab:
 - new DVB frontend drivers: ascot2e, cxd2841er, horus3a, lnbh25
 - new HDMI capture driver: tc358743
 - new driver for NetUP DVB new boards (netup_unidvb)
 - IR support for DVBSky cards (smipcie-ir)
 - Coda driver has gain macroblock tiling support
 - Renesas R-Car gains JPEG codec driver
 - new DVB platform driver for STi boards: c8sectpfe
 - added documentation for the media core kABI to device-drivers DocBook
 - lots of driver fixups, cleanups and improvements

* tag 'media/v4.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (297 commits)
  [media] c8sectpfe: Remove select on undefined LIBELF_32
  [media] i2c: fix platform_no_drv_owner.cocci warnings
  [media] cx231xx: Use wake_up_interruptible() instead of wake_up_interruptible_nr()
  [media] tc358743: only queue subdev notifications if devnode is set
  [media] tc358743: add missing Kconfig dependency/select
  [media] c8sectpfe: Use %pad to print 'dma_addr_t'
  [media] DocBook media: Fix typo "the the" in xml files
  [media] tc358743: make reset gpio optional
  [media] tc358743: set direction of reset gpio using devm_gpiod_get
  [media] dvbdev: document most of the functions/data structs
  [media] dvb_frontend.h: document the struct dvb_frontend
  [media] dvb-frontend.h: document struct dtv_frontend_properties
  [media] dvb-frontend.h: document struct dvb_frontend_ops
  [media] dvb: Use DVBFE_ALGO_HW where applicable
  [media] dvb_frontend.h: document struct analog_demod_ops
  [media] dvb_frontend.h: Document struct dvb_tuner_ops
  [media] Docbook: Document struct analog_parameters
  [media] dvb_frontend.h: get rid of dvbfe_modcod
  [media] add documentation for struct dvb_tuner_info
  [media] dvb_frontend: document dvb_frontend_tune_settings
  ...
This commit is contained in:
Linus Torvalds 2015-09-05 18:21:14 -07:00
commit 9cfcc658da
277 changed files with 18634 additions and 4331 deletions

View file

@ -307,7 +307,7 @@ static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field
/* simple bubble-sort algorithm with duplicate elimination */
static int sort_and_eliminate(u32* values, int* count)
{
int low = 0, high = 0, top = 0, temp = 0;
int low = 0, high = 0, top = 0;
int cur = 0, next = 0;
/* sanity checks */
@ -318,11 +318,8 @@ static int sort_and_eliminate(u32* values, int* count)
/* bubble sort the first @count items of the array @values */
for( top = *count; top > 0; top--) {
for( low = 0, high = 1; high < top; low++, high++) {
if( values[low] > values[high] ) {
temp = values[low];
values[low] = values[high];
values[high] = temp;
}
if( values[low] > values[high] )
swap(values[low], values[high]);
}
}

View file

@ -169,10 +169,10 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * e
/**
* Safely find needle in haystack.
*
* @param haystack Buffer to look in.
* @param hlen Number of bytes in haystack.
* @param needle Buffer to find.
* @param nlen Number of bytes in needle.
* @haystack: Buffer to look in.
* @hlen: Number of bytes in haystack.
* @needle: Buffer to find.
* @nlen: Number of bytes in needle.
* @return Pointer into haystack needle was found at, or NULL if not found.
*/
static char *findstr(char * haystack, int hlen, char * needle, int nlen)
@ -197,7 +197,7 @@ static char *findstr(char * haystack, int hlen, char * needle, int nlen)
/**
* Check CAM status.
* dvb_ca_en50221_check_camstatus - Check CAM status.
*/
static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
{
@ -240,13 +240,13 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot)
/**
* Wait for flags to become set on the STATUS register on a CAM interface,
* checking for errors and timeout.
* dvb_ca_en50221_wait_if_status - Wait for flags to become set on the STATUS
* register on a CAM interface, checking for errors and timeout.
*
* @param ca CA instance.
* @param slot Slot on interface.
* @param waitfor Flags to wait for.
* @param timeout_ms Timeout in milliseconds.
* @ca: CA instance.
* @slot: Slot on interface.
* @waitfor: Flags to wait for.
* @timeout_ms: Timeout in milliseconds.
*
* @return 0 on success, nonzero on error.
*/
@ -290,10 +290,10 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot,
/**
* Initialise the link layer connection to a CAM.
* dvb_ca_en50221_link_init - Initialise the link layer connection to a CAM.
*
* @param ca CA instance.
* @param slot Slot id.
* @ca: CA instance.
* @slot: Slot id.
*
* @return 0 on success, nonzero on failure.
*/
@ -346,14 +346,14 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
}
/**
* Read a tuple from attribute memory.
* dvb_ca_en50221_read_tuple - Read a tuple from attribute memory.
*
* @param ca CA instance.
* @param slot Slot id.
* @param address Address to read from. Updated.
* @param tupleType Tuple id byte. Updated.
* @param tupleLength Tuple length. Updated.
* @param tuple Dest buffer for tuple (must be 256 bytes). Updated.
* @ca: CA instance.
* @slot: Slot id.
* @address: Address to read from. Updated.
* @tupleType: Tuple id byte. Updated.
* @tupleLength: Tuple length. Updated.
* @tuple: Dest buffer for tuple (must be 256 bytes). Updated.
*
* @return 0 on success, nonzero on error.
*/
@ -399,11 +399,11 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot,
/**
* Parse attribute memory of a CAM module, extracting Config register, and checking
* it is a DVB CAM module.
* dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module,
* extracting Config register, and checking it is a DVB CAM module.
*
* @param ca CA instance.
* @param slot Slot id.
* @ca: CA instance.
* @slot: Slot id.
*
* @return 0 on success, <0 on failure.
*/
@ -546,10 +546,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot)
/**
* Set CAM's configoption correctly.
* dvb_ca_en50221_set_configoption - Set CAM's configoption correctly.
*
* @param ca CA instance.
* @param slot Slot containing the CAM.
* @ca: CA instance.
* @slot: Slot containing the CAM.
*/
static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
{
@ -574,15 +574,16 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
/**
* This function talks to an EN50221 CAM control interface. It reads a buffer of
* data from the CAM. The data can either be stored in a supplied buffer, or
* automatically be added to the slot's rx_buffer.
* dvb_ca_en50221_read_data - This function talks to an EN50221 CAM control
* interface. It reads a buffer of data from the CAM. The data can either
* be stored in a supplied buffer, or automatically be added to the slot's
* rx_buffer.
*
* @param ca CA instance.
* @param slot Slot to read from.
* @param ebuf If non-NULL, the data will be written to this buffer. If NULL,
* @ca: CA instance.
* @slot: Slot to read from.
* @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
* the data will be added into the buffering system as a normal fragment.
* @param ecount Size of ebuf. Ignored if ebuf is NULL.
* @ecount: Size of ebuf. Ignored if ebuf is NULL.
*
* @return Number of bytes read, or < 0 on error
*/
@ -698,14 +699,14 @@ exit:
/**
* This function talks to an EN50221 CAM control interface. It writes a buffer of data
* to a CAM.
* dvb_ca_en50221_write_data - This function talks to an EN50221 CAM control
* interface. It writes a buffer of data to a CAM.
*
* @param ca CA instance.
* @param slot Slot to write to.
* @param ebuf The data in this buffer is treated as a complete link-level packet to
* @ca: CA instance.
* @slot: Slot to write to.
* @ebuf: The data in this buffer is treated as a complete link-level packet to
* be written.
* @param count Size of ebuf.
* @count: Size of ebuf.
*
* @return Number of bytes written, or < 0 on error.
*/
@ -790,10 +791,10 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq);
/**
* A CAM has been removed => shut it down.
* dvb_ca_en50221_camready_irq - A CAM has been removed => shut it down.
*
* @param ca CA instance.
* @param slot Slot to shut down.
* @ca: CA instance.
* @slot: Slot to shut down.
*/
static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot)
{
@ -815,11 +816,11 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq);
/**
* A CAMCHANGE IRQ has occurred.
* dvb_ca_en50221_camready_irq - A CAMCHANGE IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @param change_type One of the DVB_CA_CAMCHANGE_* values.
* @ca: CA instance.
* @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values.
*/
void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type)
{
@ -844,10 +845,10 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
/**
* A CAMREADY IRQ has occurred.
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @ca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
{
@ -865,8 +866,8 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot)
/**
* An FR or DA IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @ca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
{
@ -899,7 +900,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot)
/**
* Wake up the DVB CA thread
*
* @param ca CA instance.
* @ca: CA instance.
*/
static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
{
@ -914,7 +915,7 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
/**
* Update the delay used by the thread.
*
* @param ca CA instance.
* @ca: CA instance.
*/
static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
{
@ -1177,10 +1178,10 @@ static int dvb_ca_en50221_thread(void *data)
* Real ioctl implementation.
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
*
* @param inode Inode concerned.
* @param file File concerned.
* @param cmd IOCTL command.
* @param arg Associated argument.
* @inode: Inode concerned.
* @file: File concerned.
* @cmd: IOCTL command.
* @arg: Associated argument.
*
* @return 0 on success, <0 on error.
*/
@ -1258,10 +1259,10 @@ out_unlock:
/**
* Wrapper for ioctl implementation.
*
* @param inode Inode concerned.
* @param file File concerned.
* @param cmd IOCTL command.
* @param arg Associated argument.
* @inode: Inode concerned.
* @file: File concerned.
* @cmd: IOCTL command.
* @arg: Associated argument.
*
* @return 0 on success, <0 on error.
*/
@ -1275,10 +1276,10 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
/**
* Implementation of write() syscall.
*
* @param file File structure.
* @param buf Source buffer.
* @param count Size of source buffer.
* @param ppos Position in file (ignored).
* @file: File structure.
* @buf: Source buffer.
* @count: Size of source buffer.
* @ppos: Position in file (ignored).
*
* @return Number of bytes read, or <0 on error.
*/
@ -1416,10 +1417,10 @@ nextslot:
/**
* Implementation of read() syscall.
*
* @param file File structure.
* @param buf Destination buffer.
* @param count Size of destination buffer.
* @param ppos Position in file (ignored).
* @file: File structure.
* @buf: Destination buffer.
* @count: Size of destination buffer.
* @ppos: Position in file (ignored).
*
* @return Number of bytes read, or <0 on error.
*/
@ -1519,8 +1520,8 @@ exit:
/**
* Implementation of file open syscall.
*
* @param inode Inode concerned.
* @param file File concerned.
* @inode: Inode concerned.
* @file: File concerned.
*
* @return 0 on success, <0 on failure.
*/
@ -1564,8 +1565,8 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
/**
* Implementation of file close syscall.
*
* @param inode Inode concerned.
* @param file File concerned.
* @inode: Inode concerned.
* @file: File concerned.
*
* @return 0 on success, <0 on failure.
*/
@ -1592,8 +1593,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
/**
* Implementation of poll() syscall.
*
* @param file File concerned.
* @param wait poll wait table.
* @file: File concerned.
* @wait: poll wait table.
*
* @return Standard poll mask.
*/
@ -1656,10 +1657,10 @@ static const struct dvb_device dvbdev_ca = {
/**
* Initialise a new DVB CA EN50221 interface device.
*
* @param dvb_adapter DVB adapter to attach the new CA device to.
* @param ca The dvb_ca instance.
* @param flags Flags describing the CA device (DVB_CA_FLAG_*).
* @param slot_count Number of slots supported.
* @dvb_adapter: DVB adapter to attach the new CA device to.
* @ca: The dvb_ca instance.
* @flags: Flags describing the CA device (DVB_CA_FLAG_*).
* @slot_count: Number of slots supported.
*
* @return 0 on success, nonzero on failure
*/
@ -1743,8 +1744,8 @@ EXPORT_SYMBOL(dvb_ca_en50221_release);
/**
* Release a DVB CA EN50221 interface device.
*
* @param ca_dev The dvb_device_t instance for the CA device.
* @param ca The associated dvb_ca instance.
* @ca_dev: The dvb_device_t instance for the CA device.
* @ca: The associated dvb_ca instance.
*/
void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
{

View file

@ -83,27 +83,27 @@ struct dvb_ca_en50221 {
/* Functions for reporting IRQ events */
/**
* A CAMCHANGE IRQ has occurred.
* dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @param change_type One of the DVB_CA_CAMCHANGE_* values
* @pubca: CA instance.
* @slot: Slot concerned.
* @change_type: One of the DVB_CA_CAMCHANGE_* values
*/
void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
/**
* A CAMREADY IRQ has occurred.
* dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @pubca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
/**
* An FR or a DA IRQ has occurred.
* dvb_ca_en50221_frda_irq - An FR or a DA IRQ has occurred.
*
* @param ca CA instance.
* @param slot Slot concerned.
* @ca: CA instance.
* @slot: Slot concerned.
*/
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
@ -113,21 +113,21 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
/* Initialisation/shutdown functions */
/**
* Initialise a new DVB CA device.
* dvb_ca_en50221_init - Initialise a new DVB CA device.
*
* @param dvb_adapter DVB adapter to attach the new CA device to.
* @param ca The dvb_ca instance.
* @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
* @param slot_count Number of slots supported.
* @dvb_adapter: DVB adapter to attach the new CA device to.
* @ca: The dvb_ca instance.
* @flags: Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
* @slot_count: Number of slots supported.
*
* @return 0 on success, nonzero on failure
*/
extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
/**
* Release a DVB CA device.
* dvb_ca_en50221_release - Release a DVB CA device.
*
* @param ca The associated dvb_ca instance.
* @ca: The associated dvb_ca instance.
*/
extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);

View file

@ -81,7 +81,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW)
#define FE_ALGO_HW 1
/*
* FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling.
* FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune.

View file

@ -48,6 +48,15 @@
*/
#define MAX_DELSYS 8
/**
* struct dvb_frontend_tune_settings - parameters to adjust frontend tuning
*
* @min_delay_ms: minimum delay for tuning, in ms
* @step_size: step size between two consecutive frequencies
* @max_drift: maximum drift
*
* NOTE: step_size is in Hz, for terrestrial/cable or kHz for satellite
*/
struct dvb_frontend_tune_settings {
int min_delay_ms;
int step_size;
@ -56,6 +65,20 @@ struct dvb_frontend_tune_settings {
struct dvb_frontend;
/**
* struct dvb_tuner_info - Frontend name and min/max ranges/bandwidths
*
* @name: name of the Frontend
* @frequency_min: minimal frequency supported
* @frequency_max: maximum frequency supported
* @frequency_step: frequency step
* @bandwidth_min: minimal frontend bandwidth supported
* @bandwidth_max: maximum frontend bandwidth supported
* @bandwidth_step: frontend bandwidth step
*
* NOTE: frequency parameters are in Hz, for terrestrial/cable or kHz for
* satellite.
*/
struct dvb_tuner_info {
char name[128];
@ -68,6 +91,20 @@ struct dvb_tuner_info {
u32 bandwidth_step;
};
/**
* struct analog_parameters - Parameters to tune into an analog/radio channel
*
* @frequency: Frequency used by analog TV tuner (either in 62.5 kHz step,
* for TV, or 62.5 Hz for radio)
* @mode: Tuner mode, as defined on enum v4l2_tuner_type
* @audmode: Audio mode as defined for the rxsubchans field at videodev2.h,
* e. g. V4L2_TUNER_MODE_*
* @std: TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_*
*
* Hybrid tuners should be supported by both V4L2 and DVB APIs. This
* struct contains the data that are used by the V4L2 side. To avoid
* dependencies from V4L2 headers, all enums here are declared as integers.
*/
struct analog_parameters {
unsigned int frequency;
unsigned int mode;
@ -75,42 +112,6 @@ struct analog_parameters {
u64 std;
};
enum dvbfe_modcod {
DVBFE_MODCOD_DUMMY_PLFRAME = 0,
DVBFE_MODCOD_QPSK_1_4,
DVBFE_MODCOD_QPSK_1_3,
DVBFE_MODCOD_QPSK_2_5,
DVBFE_MODCOD_QPSK_1_2,
DVBFE_MODCOD_QPSK_3_5,
DVBFE_MODCOD_QPSK_2_3,
DVBFE_MODCOD_QPSK_3_4,
DVBFE_MODCOD_QPSK_4_5,
DVBFE_MODCOD_QPSK_5_6,
DVBFE_MODCOD_QPSK_8_9,
DVBFE_MODCOD_QPSK_9_10,
DVBFE_MODCOD_8PSK_3_5,
DVBFE_MODCOD_8PSK_2_3,
DVBFE_MODCOD_8PSK_3_4,
DVBFE_MODCOD_8PSK_5_6,
DVBFE_MODCOD_8PSK_8_9,
DVBFE_MODCOD_8PSK_9_10,
DVBFE_MODCOD_16APSK_2_3,
DVBFE_MODCOD_16APSK_3_4,
DVBFE_MODCOD_16APSK_4_5,
DVBFE_MODCOD_16APSK_5_6,
DVBFE_MODCOD_16APSK_8_9,
DVBFE_MODCOD_16APSK_9_10,
DVBFE_MODCOD_32APSK_3_4,
DVBFE_MODCOD_32APSK_4_5,
DVBFE_MODCOD_32APSK_5_6,
DVBFE_MODCOD_32APSK_8_9,
DVBFE_MODCOD_32APSK_9_10,
DVBFE_MODCOD_RESERVED_1,
DVBFE_MODCOD_BPSK_1_3,
DVBFE_MODCOD_BPSK_1_4,
DVBFE_MODCOD_RESERVED_2
};
enum tuner_param {
DVBFE_TUNER_FREQUENCY = (1 << 0),
DVBFE_TUNER_TUNERSTEP = (1 << 1),
@ -121,30 +122,28 @@ enum tuner_param {
DVBFE_TUNER_DUMMY = (1 << 31)
};
/*
* ALGO_HW: (Hardware Algorithm)
* ----------------------------------------------------------------
* Devices that support this algorithm do everything in hardware
* and no software support is needed to handle them.
* Requesting these devices to LOCK is the only thing required,
* device is supposed to do everything in the hardware.
/**
* enum dvbfe_algo - defines the algorithm used to tune into a channel
*
* ALGO_SW: (Software Algorithm)
* ----------------------------------------------------------------
* @DVBFE_ALGO_HW: Hardware Algorithm -
* Devices that support this algorithm do everything in hardware
* and no software support is needed to handle them.
* Requesting these devices to LOCK is the only thing required,
* device is supposed to do everything in the hardware.
*
* @DVBFE_ALGO_SW: Software Algorithm -
* These are dumb devices, that require software to do everything
*
* ALGO_CUSTOM: (Customizable Agorithm)
* ----------------------------------------------------------------
* Devices having this algorithm can be customized to have specific
* algorithms in the frontend driver, rather than simply doing a
* software zig-zag. In this case the zigzag maybe hardware assisted
* or it maybe completely done in hardware. In all cases, usage of
* this algorithm, in conjunction with the search and track
* callbacks, utilizes the driver specific algorithm.
* @DVBFE_ALGO_CUSTOM: Customizable Agorithm -
* Devices having this algorithm can be customized to have specific
* algorithms in the frontend driver, rather than simply doing a
* software zig-zag. In this case the zigzag maybe hardware assisted
* or it maybe completely done in hardware. In all cases, usage of
* this algorithm, in conjunction with the search and track
* callbacks, utilizes the driver specific algorithm.
*
* ALGO_RECOVERY: (Recovery Algorithm)
* ----------------------------------------------------------------
* These devices have AUTO recovery capabilities from LOCK failure
* @DVBFE_ALGO_RECOVERY: Recovery Algorithm -
* These devices have AUTO recovery capabilities from LOCK failure
*/
enum dvbfe_algo {
DVBFE_ALGO_HW = (1 << 0),
@ -162,27 +161,27 @@ struct tuner_state {
u32 refclock;
};
/*
* search callback possible return status
/**
* enum dvbfe_search - search callback possible return status
*
* DVBFE_ALGO_SEARCH_SUCCESS
* The frontend search algorithm completed and returned successfully
* @DVBFE_ALGO_SEARCH_SUCCESS:
* The frontend search algorithm completed and returned successfully
*
* DVBFE_ALGO_SEARCH_ASLEEP
* The frontend search algorithm is sleeping
* @DVBFE_ALGO_SEARCH_ASLEEP:
* The frontend search algorithm is sleeping
*
* DVBFE_ALGO_SEARCH_FAILED
* The frontend search for a signal failed
* @DVBFE_ALGO_SEARCH_FAILED:
* The frontend search for a signal failed
*
* DVBFE_ALGO_SEARCH_INVALID
* The frontend search algorith was probably supplied with invalid
* parameters and the search is an invalid one
* @DVBFE_ALGO_SEARCH_INVALID:
* The frontend search algorith was probably supplied with invalid
* parameters and the search is an invalid one
*
* DVBFE_ALGO_SEARCH_ERROR
* The frontend search algorithm failed due to some error
* @DVBFE_ALGO_SEARCH_ERROR:
* The frontend search algorithm failed due to some error
*
* DVBFE_ALGO_SEARCH_AGAIN
* The frontend search algorithm was requested to search again
* @DVBFE_ALGO_SEARCH_AGAIN:
* The frontend search algorithm was requested to search again
*/
enum dvbfe_search {
DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
@ -193,7 +192,56 @@ enum dvbfe_search {
DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
};
/**
* struct dvb_tuner_ops - Tuner information and callbacks
*
* @info: embedded struct dvb_tuner_info with tuner properties
* @release: callback function called when frontend is dettached.
* drivers should free any allocated memory.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
* @suspend: callback function used to inform that the Kernel will
* suspend.
* @resume: callback function used to inform that the Kernel is
* resuming from suspend.
* @set_params: callback function used to inform the tuner to tune
* into a digital TV channel. The properties to be used
* 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.
* @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
* @get_bandwidth: get the bandwitdh used by the low pass filters
* @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband,
* should return 0.
* @get_status: returns the frontend lock status
* @get_rf_strength: returns the RF signal strengh. Used mostly to support
* analog TV and radio. Digital TV should report, instead,
* 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.
*
* NOTE: frequencies used on get_frequency and set_frequency are in Hz for
* terrestrial/cable or kHz for satellite.
*
*/
struct dvb_tuner_ops {
struct dvb_tuner_info info;
@ -237,10 +285,37 @@ struct dvb_tuner_ops {
int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
};
/**
* struct analog_demod_info - Information struct for analog TV part of the demod
*
* @name: Name of the analog TV demodulator
*/
struct analog_demod_info {
char *name;
};
/**
* struct analog_demod_ops - Demodulation information and callbacks for
* analog TV and radio
*
* @info: pointer to struct analog_demod_info
* @set_params: callback function used to inform the demod to set the
* demodulator parameters needed to decode an analog or
* radio channel. The properties are passed via
* struct @analog_params;.
* @has_signal: returns 0xffff if has signal, or 0 if it doesn't.
* @get_afc: Used only by analog TV core. Reports the frequency
* drift due to AFC.
* @tuner_status: callback function that returns tuner status bits, e. g.
* TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO.
* @standby: set the tuner to standby mode.
* @release: callback function called when frontend is dettached.
* drivers should free any allocated memory.
* @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C
* mux support instead.
* @set_config: callback function used to send some tuner-specific
* parameters.
*/
struct analog_demod_ops {
struct analog_demod_info info;
@ -260,6 +335,87 @@ struct analog_demod_ops {
struct dtv_frontend_properties;
/**
* struct dvb_frontend_ops - Demodulation information and callbacks for
* ditialt TV
*
* @info: embedded struct dvb_tuner_info with tuner properties
* @delsys: Delivery systems supported by the frontend
* @release: callback function called when frontend is dettached.
* drivers should free any allocated memory.
* @release_sec: callback function requesting that the Satelite Equipment
* Control (SEC) driver to release and free any memory
* allocated by the driver.
* @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep.
* @write: callback function used by some demod legacy drivers to
* allow other drivers to write data into their registers.
* Should not be used on new drivers.
* @tune: callback function used by demod drivers that use
* @DVBFE_ALGO_HW; to tune into a frequency.
* @get_frontend_algo: returns the desired hardware algorithm.
* @set_frontend: callback function used to inform the demod to set the
* parameters for demodulating a digital TV channel.
* The properties to be used are stored at
* @dvb_frontend.dtv_property_cache;. The demod can change
* the parameters to reflect the changes needed for the
* channel to be decoded, and update statistics.
* @get_tune_settings: callback function
* @get_frontend: callback function used to inform the parameters
* actuall in use. The properties to be used are stored at
* @dvb_frontend.dtv_property_cache; and update
* statistics. Please notice that it should not return
* an error code if the statistics are not available
* because the demog is not locked.
* @read_status: returns the locking status of the frontend.
* @read_ber: legacy callback function to return the bit error rate.
* Newer drivers should provide such info via DVBv5 API,
* e. g. @set_frontend;/@get_frontend;, implementing this
* callback only if DVBv3 API compatibility is wanted.
* @read_signal_strength: legacy callback function to return the signal
* strength. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_snr: legacy callback function to return the Signal/Noise
* rate. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_ucblocks: legacy callback function to return the Uncorrected Error
* Blocks. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend;/@get_frontend;,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @diseqc_reset_overload: callback function to implement the
* FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite)
* @diseqc_send_master_cmd: callback function to implement the
* FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite).
* @diseqc_recv_slave_reply: callback function to implement the
* FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite)
* @diseqc_send_burst: callback function to implement the
* FE_DISEQC_SEND_BURST ioctl (only Satellite).
* @set_tone: callback function to implement the
* FE_SET_TONE ioctl (only Satellite).
* @set_voltage: callback function to implement the
* FE_SET_VOLTAGE ioctl (only Satellite).
* @enable_high_lnb_voltage: callback function to implement the
* 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).
* @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.
* @set_lna: callback function to power on/off/auto the LNA.
* @search: callback function used on some custom algo search algos.
* @tuner_ops: pointer to struct dvb_tuner_ops
* @analog_ops: pointer to struct analog_demod_ops
* @set_property: callback function to allow the frontend to validade
* incoming properties. Should not be used on new drivers.
* @get_property: callback function to allow the frontend to override
* outcoming properties. Should not be used on new drivers.
*/
struct dvb_frontend_ops {
struct dvb_frontend_info info;
@ -280,6 +436,7 @@ struct dvb_frontend_ops {
unsigned int mode_flags,
unsigned int *delay,
enum fe_status *status);
/* get frontend tuning algorithm from the module */
enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
@ -324,6 +481,7 @@ struct dvb_frontend_ops {
#ifdef __DVB_CORE__
#define MAX_EVENT 8
/* Used only internally at dvb_frontend.c */
struct dvb_fe_events {
struct dvb_frontend_event events[MAX_EVENT];
int eventw;
@ -334,13 +492,83 @@ struct dvb_fe_events {
};
#endif
/**
* struct dtv_frontend_properties - contains a list of properties that are
* specific to a digital TV standard.
*
* @frequency: frequency in Hz for terrestrial/cable or in kHz for
* Satellite
* @modulation: Frontend modulation type
* @voltage: SEC voltage (only Satellite)
* @sectone: SEC tone mode (only Satellite)
* @inversion: Spectral inversion
* @fec_inner: Forward error correction inner Code Rate
* @transmission_mode: Transmission Mode
* @bandwidth_hz: Bandwidth, in Hz. A zero value means that userspace
* wants to autodetect.
* @guard_interval: Guard Interval
* @hierarchy: Hierarchy
* @symbol_rate: Symbol Rate
* @code_rate_HP: high priority stream code rate
* @code_rate_LP: low priority stream code rate
* @pilot: Enable/disable/autodetect pilot tones
* @rolloff: Rolloff factor (alpha)
* @delivery_system: FE delivery system (e. g. digital TV standard)
* @interleaving: interleaving
* @isdbt_partial_reception: ISDB-T partial reception (only ISDB standard)
* @isdbt_sb_mode: ISDB-T Sound Broadcast (SB) mode (only ISDB standard)
* @isdbt_sb_subchannel: ISDB-T SB subchannel (only ISDB standard)
* @isdbt_sb_segment_idx: ISDB-T SB segment index (only ISDB standard)
* @isdbt_sb_segment_count: ISDB-T SB segment count (only ISDB standard)
* @isdbt_layer_enabled: ISDB Layer enabled (only ISDB standard)
* @layer: ISDB per-layer data (only ISDB standard)
* @layer.segment_count: Segment Count;
* @layer.fec: per layer code rate;
* @layer.modulation: per layer modulation;
* @layer.interleaving: per layer interleaving.
* @stream_id: If different than zero, enable substream filtering, if
* hardware supports (DVB-S2 and DVB-T2).
* @atscmh_fic_ver: Version number of the FIC (Fast Information Channel)
* signaling data (only ATSC-M/H)
* @atscmh_parade_id: Parade identification number (only ATSC-M/H)
* @atscmh_nog: Number of MH groups per MH subframe for a designated
* parade (only ATSC-M/H)
* @atscmh_tnog: Total number of MH groups including all MH groups
* belonging to all MH parades in one MH subframe
* (only ATSC-M/H)
* @atscmh_sgn: Start group number (only ATSC-M/H)
* @atscmh_prc: Parade repetition cycle (only ATSC-M/H)
* @atscmh_rs_frame_mode: Reed Solomon (RS) frame mode (only ATSC-M/H)
* @atscmh_rs_frame_ensemble: RS frame ensemble (only ATSC-M/H)
* @atscmh_rs_code_mode_pri: RS code mode pri (only ATSC-M/H)
* @atscmh_rs_code_mode_sec: RS code mode sec (only ATSC-M/H)
* @atscmh_sccc_block_mode: Series Concatenated Convolutional Code (SCCC)
* Block Mode (only ATSC-M/H)
* @atscmh_sccc_code_mode_a: SCCC code mode A (only ATSC-M/H)
* @atscmh_sccc_code_mode_b: SCCC code mode B (only ATSC-M/H)
* @atscmh_sccc_code_mode_c: SCCC code mode C (only ATSC-M/H)
* @atscmh_sccc_code_mode_d: SCCC code mode D (only ATSC-M/H)
* @lna: Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA)
* @strength: DVBv5 API statistics: Signal Strength
* @cnr: DVBv5 API statistics: Signal to Noise ratio of the
* (main) carrier
* @pre_bit_error: DVBv5 API statistics: pre-Viterbi bit error count
* @pre_bit_count: DVBv5 API statistics: pre-Viterbi bit count
* @post_bit_error: DVBv5 API statistics: post-Viterbi bit error count
* @post_bit_count: DVBv5 API statistics: post-Viterbi bit count
* @block_error: DVBv5 API statistics: block error count
* @block_count: DVBv5 API statistics: block count
*
* NOTE: derivated statistics like Uncorrected Error blocks (UCE) are
* calculated on userspace.
*
* Only a subset of the properties are needed for a given delivery system.
* For more info, consult the media_api.html with the documentation of the
* Userspace API.
*/
struct dtv_frontend_properties {
/* Cache State */
u32 state;
u32 frequency;
enum fe_modulation modulation;
enum fe_modulation modulation;
enum fe_sec_voltage voltage;
enum fe_sec_tone_mode sectone;
@ -407,6 +635,11 @@ struct dtv_frontend_properties {
struct dtv_fe_stats post_bit_count;
struct dtv_fe_stats block_error;
struct dtv_fe_stats block_count;
/* private: */
/* Cache State */
u32 state;
};
#define DVB_FE_NO_EXIT 0
@ -414,6 +647,25 @@ struct dtv_frontend_properties {
#define DVB_FE_DEVICE_REMOVED 2
#define DVB_FE_DEVICE_RESUME 3
/**
* struct dvb_frontend - Frontend structure to be used on drivers.
*
* @ops: embedded struct dvb_frontend_ops
* @dvb: pointer to struct dvb_adapter
* @demodulator_priv: demod private data
* @tuner_priv: tuner private data
* @frontend_priv: frontend private data
* @sec_priv: SEC private data
* @analog_demod_priv: Analog demod private data
* @dtv_property_cache: embedded struct dtv_frontend_properties
* @callback: callback function used on some drivers to call
* either the tuner or the demodulator.
* @id: Frontend ID
* @exit: Used to inform the DVB core that the frontend
* thread should exit (usually, means that the hardware
* got disconnected.
*/
struct dvb_frontend {
struct dvb_frontend_ops ops;
struct dvb_adapter *dvb;

View file

@ -25,33 +25,38 @@
#include <linux/types.h>
/**
* computes log2 of a value; the result is shifted left by 24 bits
* cintlog2 - computes log2 of a value; the result is shifted left by 24 bits
*
* @value: The value (must be != 0)
*
* to use rational values you can use the following method:
* intlog2(value) = intlog2(value * 2^x) - x * 2^24
*
* example: intlog2(8) will give 3 << 24 = 3 * 2^24
* example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
* example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
* Some usecase examples:
* intlog2(8) will give 3 << 24 = 3 * 2^24
* intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
* intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
*
* @param value The value (must be != 0)
* @return log2(value) * 2^24
*
* return: log2(value) * 2^24
*/
extern unsigned int intlog2(u32 value);
/**
* computes log10 of a value; the result is shifted left by 24 bits
* intlog10 - computes log10 of a value; the result is shifted left by 24 bits
*
* @value: The value (must be != 0)
*
* to use rational values you can use the following method:
* intlog10(value) = intlog10(value * 10^x) - x * 2^24
*
* example: intlog10(1000) will give 3 << 24 = 3 * 2^24
* An usecase example:
* intlog10(1000) will give 3 << 24 = 3 * 2^24
* due to the implementation intlog10(1000) might be not exactly 3 * 2^24
*
* look at intlog2 for similar examples
*
* @param value The value (must be != 0)
* @return log10(value) * 2^24
* return: log10(value) * 2^24
*/
extern unsigned int intlog10(u32 value);

View file

@ -709,7 +709,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
if (!priv->ule_dbit) {
/* dest_addr buffer is only valid if priv->ule_dbit == 0 */
memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
memset(ethh->h_source, 0, ETH_ALEN);
eth_zero_addr(ethh->h_source);
}
else /* zeroize source and dest */
memset( ethh, 0, ETH_ALEN*2 );

View file

@ -45,33 +45,33 @@ struct dvb_ringbuffer {
/*
** Notes:
** ------
** (1) For performance reasons read and write routines don't check buffer sizes
** and/or number of bytes free/available. This has to be done before these
** routines are called. For example:
**
** *** write <buflen> bytes ***
** free = dvb_ringbuffer_free(rbuf);
** if (free >= buflen)
** count = dvb_ringbuffer_write(rbuf, buffer, buflen);
** else
** ...
**
** *** read min. 1000, max. <bufsize> bytes ***
** avail = dvb_ringbuffer_avail(rbuf);
** if (avail >= 1000)
** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
** else
** ...
**
** (2) If there is exactly one reader and one writer, there is no need
** to lock read or write operations.
** Two or more readers must be locked against each other.
** Flushing the buffer counts as a read operation.
** Resetting the buffer counts as a read and write operation.
** Two or more writers must be locked against each other.
*/
* Notes:
* ------
* (1) For performance reasons read and write routines don't check buffer sizes
* and/or number of bytes free/available. This has to be done before these
* routines are called. For example:
*
* *** write @buflen: bytes ***
* free = dvb_ringbuffer_free(rbuf);
* if (free >= buflen)
* count = dvb_ringbuffer_write(rbuf, buffer, buflen);
* else
* ...
*
* *** read min. 1000, max. @bufsize: bytes ***
* avail = dvb_ringbuffer_avail(rbuf);
* if (avail >= 1000)
* count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
* else
* ...
*
* (2) If there is exactly one reader and one writer, there is no need
* to lock read or write operations.
* Two or more readers must be locked against each other.
* Flushing the buffer counts as a read operation.
* Resetting the buffer counts as a read and write operation.
* Two or more writers must be locked against each other.
*/
/* initialize ring buffer, lock and queue */
extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);
@ -87,9 +87,9 @@ extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
/*
** Reset the read and write pointers to zero and flush the buffer
** This counts as a read and write operation
*/
* Reset the read and write pointers to zero and flush the buffer
* This counts as a read and write operation
*/
extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);
@ -101,19 +101,19 @@ extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
/* flush buffer protected by spinlock and wake-up waiting task(s) */
extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
/* peek at byte <offs> in the buffer */
/* peek at byte @offs: in the buffer */
#define DVB_RINGBUFFER_PEEK(rbuf,offs) \
(rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size]
/* advance read ptr by <num> bytes */
/* advance read ptr by @num: bytes */
#define DVB_RINGBUFFER_SKIP(rbuf,num) \
(rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
/*
** read <len> bytes from ring buffer into <buf>
** <usermem> specifies whether <buf> resides in user space
** returns number of bytes transferred or -EFAULT
*/
* read @len: bytes from ring buffer into @buf:
* @usermem: specifies whether @buf: resides in user space
* returns number of bytes transferred or -EFAULT
*/
extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
u8 __user *buf, size_t len);
extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
@ -127,9 +127,9 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
{ (rbuf)->data[(rbuf)->pwrite]=(byte); \
(rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
/*
** write <len> bytes to ring buffer
** <usermem> specifies whether <buf> resides in user space
** returns number of bytes transferred or -EFAULT
* write @len: bytes to ring buffer
* @usermem: specifies whether @buf: resides in user space
* returns number of bytes transferred or -EFAULT
*/
extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
size_t len);
@ -138,48 +138,63 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
/**
* Write a packet into the ringbuffer.
* dvb_ringbuffer_pkt_write - Write a packet into the ringbuffer.
*
* <rbuf> Ringbuffer to write to.
* <buf> Buffer to write.
* <len> Length of buffer (currently limited to 65535 bytes max).
* @rbuf: Ringbuffer to write to.
* @buf: Buffer to write.
* @len: Length of buffer (currently limited to 65535 bytes max).
* returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
*/
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
size_t len);
/**
* Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
* does NOT update the read pointer in the ringbuffer. You must use
* dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.
* dvb_ringbuffer_pkt_read_user - Read from a packet in the ringbuffer.
* Note: unlike dvb_ringbuffer_read(), this does NOT update the read pointer
* in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a
* packet as no longer required.
*
* @rbuf: Ringbuffer concerned.
* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
* @offset: Offset into packet to read from.
* @buf: Destination buffer for data.
* @len: Size of destination buffer.
*
* <rbuf> Ringbuffer concerned.
* <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
* <offset> Offset into packet to read from.
* <buf> Destination buffer for data.
* <len> Size of destination buffer.
* <usermem> Set to 1 if <buf> is in userspace.
* returns Number of bytes read, or -EFAULT.
*/
extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
int offset, u8 __user *buf, size_t len);
/**
* dvb_ringbuffer_pkt_read - Read from a packet in the ringbuffer.
* Note: unlike dvb_ringbuffer_read_user(), this DOES update the read pointer
* in the ringbuffer.
*
* @rbuf: Ringbuffer concerned.
* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
* @offset: Offset into packet to read from.
* @buf: Destination buffer for data.
* @len: Size of destination buffer.
*
* returns Number of bytes read, or -EFAULT.
*/
extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
int offset, u8 *buf, size_t len);
/**
* Dispose of a packet in the ring buffer.
* dvb_ringbuffer_pkt_dispose - Dispose of a packet in the ring buffer.
*
* <rbuf> Ring buffer concerned.
* <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
* @rbuf: Ring buffer concerned.
* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().
*/
extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
/**
* Get the index of the next packet in a ringbuffer.
* dvb_ringbuffer_pkt_next - Get the index of the next packet in a ringbuffer.
*
* <rbuf> Ringbuffer concerned.
* <idx> Previous packet index, or -1 to return the first packet index.
* <pktlen> On success, will be updated to contain the length of the packet in bytes.
* @rbuf: Ringbuffer concerned.
* @idx: Previous packet index, or -1 to return the first packet index.
* @pktlen: On success, will be updated to contain the length of the packet in bytes.
* returns Packet index (if >=0), or -1 if no packets available.
*/
extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen);

View file

@ -57,6 +57,25 @@
struct dvb_frontend;
/**
* struct dvb_adapter - represents a Digital TV adapter using Linux DVB API
*
* @num: Number of the adapter
* @list_head: List with the DVB adapters
* @device_list: List with the DVB devices
* @name: Name of the adapter
* @proposed_mac: proposed MAC address for the adapter
* @priv: private data
* @device: pointer to struct device
* @module: pointer to struct module
* @mfe_shared: mfe shared: indicates mutually exclusive frontends
* Thie usage of this flag is currently deprecated
* @mfe_dvbdev: Frontend device in use, in the case of MFE
* @mfe_lock: Lock to prevent using the other frontends when MFE is
* used.
* @mdev: pointer to struct media_device, used when the media
* controller is used.
*/
struct dvb_adapter {
int num;
struct list_head list_head;
@ -78,7 +97,34 @@ struct dvb_adapter {
#endif
};
/**
* struct dvb_device - represents a DVB device node
*
* @list_head: List head with all DVB devices
* @fops: pointer to struct file_operations
* @adapter: pointer to the adapter that holds this device node
* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
* @minor: devnode minor number. Major number is always DVB_MAJOR.
* @id: device ID number, inside the adapter
* @readers: Initialized by the caller. Each call to open() in Read Only mode
* decreases this counter by one.
* @writers: Initialized by the caller. Each call to open() in Read/Write
* mode decreases this counter by one.
* @users: Initialized by the caller. Each call to open() in any mode
* decreases this counter by one.
* @wait_queue: wait queue, used to wait for certain events inside one of
* the DVB API callers
* @kernel_ioctl: callback function used to handle ioctl calls from userspace.
* @name: Name to be used for the device at the Media Controller
* @entity: pointer to struct media_entity associated with the device node
* @pads: pointer to struct media_pad associated with @entity;
* @priv: private data
*
* This structure is used by the DVB core (frontend, CA, net, demux) in
* order to create the device nodes. Usually, driver should not initialize
* this struct diretly.
*/
struct dvb_device {
struct list_head list_head;
const struct file_operations *fops;
@ -109,19 +155,55 @@ struct dvb_device {
void *priv;
};
/**
* dvb_register_adapter - Registers a new DVB adapter
*
* @adap: pointer to struct dvb_adapter
* @name: Adapter's name
* @module: initialized with THIS_MODULE at the caller
* @device: pointer to struct device that corresponds to the device driver
* @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
* to select among them. Typically, initialized with:
* DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
*/
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
struct module *module, struct device *device,
short *adapter_nums);
extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
struct module *module, struct device *device,
short *adapter_nums);
extern int dvb_unregister_adapter (struct dvb_adapter *adap);
/**
* dvb_unregister_adapter - Unregisters a DVB adapter
*
* @adap: pointer to struct dvb_adapter
*/
int dvb_unregister_adapter(struct dvb_adapter *adap);
extern int dvb_register_device (struct dvb_adapter *adap,
struct dvb_device **pdvbdev,
const struct dvb_device *template,
void *priv,
int type);
/**
* dvb_register_device - Registers a new DVB device
*
* @adap: pointer to struct dvb_adapter
* @pdvbdev: pointer to the place where the new struct dvb_device will be
* stored
* @template: Template used to create &pdvbdev;
* @device: pointer to struct device that corresponds to the device driver
* @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
* to select among them. Typically, initialized with:
* DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
* @priv: private data
* @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND,
* DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET
*/
int dvb_register_device(struct dvb_adapter *adap,
struct dvb_device **pdvbdev,
const struct dvb_device *template,
void *priv,
int type);
extern void dvb_unregister_device (struct dvb_device *dvbdev);
/**
* dvb_unregister_device - Unregisters a DVB device
*
* @dvbdev: pointer to struct dvb_device
*/
void dvb_unregister_device(struct dvb_device *dvbdev);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
void dvb_create_media_graph(struct dvb_adapter *adap);
@ -136,17 +218,17 @@ static inline void dvb_create_media_graph(struct dvb_adapter *adap) {}
#define dvb_register_media_controller(a, b) {}
#endif
extern int dvb_generic_open (struct inode *inode, struct file *file);
extern int dvb_generic_release (struct inode *inode, struct file *file);
extern long dvb_generic_ioctl (struct file *file,
int dvb_generic_open (struct inode *inode, struct file *file);
int dvb_generic_release (struct inode *inode, struct file *file);
long dvb_generic_ioctl (struct file *file,
unsigned int cmd, unsigned long arg);
/* we don't mess with video_usercopy() any more,
we simply define out own dvb_usercopy(), which will hopefully become
generic_usercopy() someday... */
extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
int (*func)(struct file *file, unsigned int cmd, void *arg));
int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
int (*func)(struct file *file, unsigned int cmd, void *arg));
/** generic DVB attach function. */
#ifdef CONFIG_MEDIA_ATTACH

View file

@ -1,5 +1,5 @@
menu "Customise DVB Frontends"
visible if !MEDIA_SUBDRV_AUTOSELECT
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@ -264,6 +264,7 @@ config DVB_MB86A16
config DVB_TDA10071
tristate "NXP TDA10071"
depends on DVB_CORE && I2C
select REGMAP
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
@ -450,6 +451,13 @@ config DVB_CXD2820R
help
Say Y when you want to support this frontend.
config DVB_CXD2841ER
tristate "Sony CXD2841ER"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2830
tristate "Realtek RTL2830 DVB-T"
depends on DVB_CORE && I2C && I2C_MUX
@ -712,6 +720,14 @@ comment "SEC control devices for DVB-S"
source "drivers/media/dvb-frontends/drx39xyj/Kconfig"
config DVB_LNBH25
tristate "LNBH25 SEC controller"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chip.
Say Y when you want to support this chip.
config DVB_LNBP21
tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
@ -815,6 +831,20 @@ config DVB_AF9033
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
config DVB_HORUS3A
tristate "Sony Horus3A tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_ASCOT2E
tristate "Sony Ascot2E tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
comment "Tools to develop new frontends"
config DVB_DUMMY_FE

View file

@ -57,6 +57,7 @@ obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_LGDT3306A) += lgdt3306a.o
obj-$(CONFIG_DVB_LG2160) += lg2160.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
@ -105,6 +106,7 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
obj-$(CONFIG_DVB_STV0367) += stv0367.o
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
obj-$(CONFIG_DVB_CXD2841ER) += cxd2841er.o
obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_SI2165) += si2165.o
@ -118,3 +120,5 @@ obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o
obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
obj-$(CONFIG_DVB_TC90522) += tc90522.o
obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o

View file

@ -12,163 +12,69 @@
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dvb_frontend.h"
#include "a8293.h"
struct a8293_priv {
u8 i2c_addr;
struct i2c_adapter *i2c;
struct a8293_dev {
struct i2c_client *client;
u8 reg[2];
};
static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
{
int ret;
struct i2c_msg msg[1] = {
{
.addr = priv->i2c_addr,
.len = len,
.buf = val,
}
};
if (rd)
msg[0].flags = I2C_M_RD;
else
msg[0].flags = 0;
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret == 1) {
ret = 0;
} else {
dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
KBUILD_MODNAME, ret, rd);
ret = -EREMOTEIO;
}
return ret;
}
static int a8293_wr(struct a8293_priv *priv, u8 *val, int len)
{
return a8293_i2c(priv, val, len, 0);
}
static int a8293_rd(struct a8293_priv *priv, u8 *val, int len)
{
return a8293_i2c(priv, val, len, 1);
}
static int a8293_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage fe_sec_voltage)
enum fe_sec_voltage fe_sec_voltage)
{
struct a8293_priv *priv = fe->sec_priv;
struct a8293_dev *dev = fe->sec_priv;
struct i2c_client *client = dev->client;
int ret;
u8 reg0, reg1;
dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
fe_sec_voltage);
dev_dbg(&client->dev, "fe_sec_voltage=%d\n", fe_sec_voltage);
switch (fe_sec_voltage) {
case SEC_VOLTAGE_OFF:
/* ENB=0 */
priv->reg[0] = 0x10;
reg0 = 0x10;
break;
case SEC_VOLTAGE_13:
/* VSEL0=1, VSEL1=0, VSEL2=0, VSEL3=0, ENB=1*/
priv->reg[0] = 0x31;
reg0 = 0x31;
break;
case SEC_VOLTAGE_18:
/* VSEL0=0, VSEL1=0, VSEL2=0, VSEL3=1, ENB=1*/
priv->reg[0] = 0x38;
reg0 = 0x38;
break;
default:
ret = -EINVAL;
goto err;
}
ret = a8293_wr(priv, &priv->reg[0], 1);
if (ret)
goto err;
usleep_range(1500, 50000);
return ret;
err:
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static void a8293_release_sec(struct dvb_frontend *fe)
{
a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
kfree(fe->sec_priv);
fe->sec_priv = NULL;
}
struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg)
{
int ret;
struct a8293_priv *priv = NULL;
u8 buf[2];
/* allocate memory for the internal priv */
priv = kzalloc(sizeof(struct a8293_priv), GFP_KERNEL);
if (priv == NULL) {
ret = -ENOMEM;
goto err;
if (reg0 != dev->reg[0]) {
ret = i2c_master_send(client, &reg0, 1);
if (ret < 0)
goto err;
dev->reg[0] = reg0;
}
/* setup the priv */
priv->i2c = i2c;
priv->i2c_addr = cfg->i2c_addr;
fe->sec_priv = priv;
/* check if the SEC is there */
ret = a8293_rd(priv, buf, 2);
if (ret)
goto err;
/* ENB=0 */
priv->reg[0] = 0x10;
ret = a8293_wr(priv, &priv->reg[0], 1);
if (ret)
goto err;
/* TMODE=0, TGATE=1 */
priv->reg[1] = 0x82;
ret = a8293_wr(priv, &priv->reg[1], 1);
if (ret)
goto err;
reg1 = 0x82;
if (reg1 != dev->reg[1]) {
ret = i2c_master_send(client, &reg1, 1);
if (ret < 0)
goto err;
dev->reg[1] = reg1;
}
fe->ops.release_sec = a8293_release_sec;
/* override frontend ops */
fe->ops.set_voltage = a8293_set_voltage;
dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
KBUILD_MODNAME);
return fe;
usleep_range(1500, 50000);
return 0;
err:
dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
kfree(priv);
return NULL;
dev_dbg(&client->dev, "failed=%d\n", ret);
return ret;
}
EXPORT_SYMBOL(a8293_attach);
static int a8293_probe(struct i2c_client *client,
const struct i2c_device_id *id)
const struct i2c_device_id *id)
{
struct a8293_priv *dev;
struct a8293_dev *dev;
struct a8293_platform_data *pdata = client->dev.platform_data;
struct dvb_frontend *fe = pdata->dvb_frontend;
int ret;
@ -181,29 +87,14 @@ static int a8293_probe(struct i2c_client *client,
}
dev->client = client;
dev->i2c = client->adapter;
dev->i2c_addr = client->addr;
/* check if the SEC is there */
ret = a8293_rd(dev, buf, 2);
if (ret)
goto err_kfree;
/* ENB=0 */
dev->reg[0] = 0x10;
ret = a8293_wr(dev, &dev->reg[0], 1);
if (ret)
goto err_kfree;
/* TMODE=0, TGATE=1 */
dev->reg[1] = 0x82;
ret = a8293_wr(dev, &dev->reg[1], 1);
if (ret)
ret = i2c_master_recv(client, buf, 2);
if (ret < 0)
goto err_kfree;
/* override frontend ops */
fe->ops.set_voltage = a8293_set_voltage;
fe->sec_priv = dev;
i2c_set_clientdata(client, dev);
@ -234,7 +125,6 @@ MODULE_DEVICE_TABLE(i2c, a8293_id_table);
static struct i2c_driver a8293_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "a8293",
.suppress_bind_attrs = true,
},

View file

@ -12,17 +12,12 @@
* 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.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef A8293_H
#define A8293_H
#include "dvb_frontend.h"
#include <linux/kconfig.h>
/*
* I2C address
@ -37,21 +32,4 @@ struct a8293_platform_data {
struct dvb_frontend *dvb_frontend;
};
struct a8293_config {
u8 i2c_addr;
};
#if IS_REACHABLE(CONFIG_DVB_A8293)
extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg);
#else
static inline struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, const struct a8293_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* A8293_H */

View file

@ -1387,7 +1387,6 @@ MODULE_DEVICE_TABLE(i2c, af9033_id_table);
static struct i2c_driver af9033_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "af9033",
},
.probe = af9033_probe,

View file

@ -0,0 +1,548 @@
/*
* ascot2e.c
*
* Sony Ascot3E DVB-T/T2/C/C2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "ascot2e.h"
#include "dvb_frontend.h"
#define MAX_WRITE_REGSIZE 10
enum ascot2e_state {
STATE_UNKNOWN,
STATE_SLEEP,
STATE_ACTIVE
};
struct ascot2e_priv {
u32 frequency;
u8 i2c_address;
struct i2c_adapter *i2c;
enum ascot2e_state state;
void *set_tuner_data;
int (*set_tuner)(void *, int);
};
enum ascot2e_tv_system_t {
ASCOT2E_DTV_DVBT_5,
ASCOT2E_DTV_DVBT_6,
ASCOT2E_DTV_DVBT_7,
ASCOT2E_DTV_DVBT_8,
ASCOT2E_DTV_DVBT2_1_7,
ASCOT2E_DTV_DVBT2_5,
ASCOT2E_DTV_DVBT2_6,
ASCOT2E_DTV_DVBT2_7,
ASCOT2E_DTV_DVBT2_8,
ASCOT2E_DTV_DVBC_6,
ASCOT2E_DTV_DVBC_8,
ASCOT2E_DTV_DVBC2_6,
ASCOT2E_DTV_DVBC2_8,
ASCOT2E_DTV_UNKNOWN
};
struct ascot2e_band_sett {
u8 if_out_sel;
u8 agc_sel;
u8 mix_oll;
u8 rf_gain;
u8 if_bpf_gc;
u8 fif_offset;
u8 bw_offset;
u8 bw;
u8 rf_oldet;
u8 if_bpf_f0;
};
#define ASCOT2E_AUTO 0xff
#define ASCOT2E_OFFSET(ofs) ((u8)(ofs) & 0x1F)
#define ASCOT2E_BW_6 0x00
#define ASCOT2E_BW_7 0x01
#define ASCOT2E_BW_8 0x02
#define ASCOT2E_BW_1_7 0x03
static struct ascot2e_band_sett ascot2e_sett[] = {
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-10), ASCOT2E_OFFSET(-16), ASCOT2E_BW_1_7, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-8), ASCOT2E_BW_6, 0x09, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03,
ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(-1), ASCOT2E_BW_8, 0x09, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01,
ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_6, 0x09, 0x00 },
{ ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01,
ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(2), ASCOT2E_BW_8, 0x09, 0x00 }
};
static void ascot2e_i2c_debug(struct ascot2e_priv *priv,
u8 reg, u8 write, const u8 *data, u32 len)
{
dev_dbg(&priv->i2c->dev, "ascot2e: I2C %s reg 0x%02x size %d\n",
(write == 0 ? "read" : "write"), reg, len);
print_hex_dump_bytes("ascot2e: I2C data: ",
DUMP_PREFIX_OFFSET, data, len);
}
static int ascot2e_write_regs(struct ascot2e_priv *priv,
u8 reg, const u8 *data, u32 len)
{
int ret;
u8 buf[MAX_WRITE_REGSIZE + 1];
struct i2c_msg msg[1] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = len + 1,
.buf = buf,
}
};
if (len + 1 >= sizeof(buf)) {
dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
reg, len + 1);
return -E2BIG;
}
ascot2e_i2c_debug(priv, reg, 1, data, len);
buf[0] = reg;
memcpy(&buf[1], data, len);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: i2c wr failed=%d reg=%02x len=%d\n",
KBUILD_MODNAME, ret, reg, len);
return ret;
}
return 0;
}
static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
{
return ascot2e_write_regs(priv, reg, &val, 1);
}
static int ascot2e_read_regs(struct ascot2e_priv *priv,
u8 reg, u8 *val, u32 len)
{
int ret;
struct i2c_msg msg[2] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = 1,
.buf = &reg,
}, {
.addr = priv->i2c_address,
.flags = I2C_M_RD,
.len = len,
.buf = val,
}
};
ret = i2c_transfer(priv->i2c, &msg[0], 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: I2C rw failed=%d addr=%02x reg=%02x\n",
KBUILD_MODNAME, ret, priv->i2c_address, reg);
return ret;
}
ret = i2c_transfer(priv->i2c, &msg[1], 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: i2c rd failed=%d addr=%02x reg=%02x\n",
KBUILD_MODNAME, ret, priv->i2c_address, reg);
return ret;
}
ascot2e_i2c_debug(priv, reg, 0, val, len);
return 0;
}
static int ascot2e_read_reg(struct ascot2e_priv *priv, u8 reg, u8 *val)
{
return ascot2e_read_regs(priv, reg, val, 1);
}
static int ascot2e_set_reg_bits(struct ascot2e_priv *priv,
u8 reg, u8 data, u8 mask)
{
int res;
u8 rdata;
if (mask != 0xff) {
res = ascot2e_read_reg(priv, reg, &rdata);
if (res != 0)
return res;
data = ((data & mask) | (rdata & (mask ^ 0xFF)));
}
return ascot2e_write_reg(priv, reg, data);
}
static int ascot2e_enter_power_save(struct ascot2e_priv *priv)
{
u8 data[2];
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_SLEEP)
return 0;
data[0] = 0x00;
data[1] = 0x04;
ascot2e_write_regs(priv, 0x14, data, 2);
ascot2e_write_reg(priv, 0x50, 0x01);
priv->state = STATE_SLEEP;
return 0;
}
static int ascot2e_leave_power_save(struct ascot2e_priv *priv)
{
u8 data[2] = { 0xFB, 0x0F };
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_ACTIVE)
return 0;
ascot2e_write_regs(priv, 0x14, data, 2);
ascot2e_write_reg(priv, 0x50, 0x00);
priv->state = STATE_ACTIVE;
return 0;
}
static int ascot2e_init(struct dvb_frontend *fe)
{
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
return ascot2e_leave_power_save(priv);
}
static int ascot2e_release(struct dvb_frontend *fe)
{
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static int ascot2e_sleep(struct dvb_frontend *fe)
{
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
ascot2e_enter_power_save(priv);
return 0;
}
static enum ascot2e_tv_system_t ascot2e_get_tv_system(struct dvb_frontend *fe)
{
enum ascot2e_tv_system_t system = ASCOT2E_DTV_UNKNOWN;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct ascot2e_priv *priv = fe->tuner_priv;
if (p->delivery_system == SYS_DVBT) {
if (p->bandwidth_hz <= 5000000)
system = ASCOT2E_DTV_DVBT_5;
else if (p->bandwidth_hz <= 6000000)
system = ASCOT2E_DTV_DVBT_6;
else if (p->bandwidth_hz <= 7000000)
system = ASCOT2E_DTV_DVBT_7;
else if (p->bandwidth_hz <= 8000000)
system = ASCOT2E_DTV_DVBT_8;
else {
system = ASCOT2E_DTV_DVBT_8;
p->bandwidth_hz = 8000000;
}
} else if (p->delivery_system == SYS_DVBT2) {
if (p->bandwidth_hz <= 5000000)
system = ASCOT2E_DTV_DVBT2_5;
else if (p->bandwidth_hz <= 6000000)
system = ASCOT2E_DTV_DVBT2_6;
else if (p->bandwidth_hz <= 7000000)
system = ASCOT2E_DTV_DVBT2_7;
else if (p->bandwidth_hz <= 8000000)
system = ASCOT2E_DTV_DVBT2_8;
else {
system = ASCOT2E_DTV_DVBT2_8;
p->bandwidth_hz = 8000000;
}
} else if (p->delivery_system == SYS_DVBC_ANNEX_A) {
if (p->bandwidth_hz <= 6000000)
system = ASCOT2E_DTV_DVBC_6;
else if (p->bandwidth_hz <= 8000000)
system = ASCOT2E_DTV_DVBC_8;
}
dev_dbg(&priv->i2c->dev,
"%s(): ASCOT2E DTV system %d (delsys %d, bandwidth %d)\n",
__func__, (int)system, p->delivery_system, p->bandwidth_hz);
return system;
}
static int ascot2e_set_params(struct dvb_frontend *fe)
{
u8 data[10];
u32 frequency;
enum ascot2e_tv_system_t tv_system;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct ascot2e_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n",
__func__, p->frequency / 1000);
tv_system = ascot2e_get_tv_system(fe);
if (tv_system == ASCOT2E_DTV_UNKNOWN) {
dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n",
__func__);
return -EINVAL;
}
if (priv->set_tuner)
priv->set_tuner(priv->set_tuner_data, 1);
frequency = roundup(p->frequency / 1000, 25);
if (priv->state == STATE_SLEEP)
ascot2e_leave_power_save(priv);
/* IF_OUT_SEL / AGC_SEL setting */
data[0] = 0x00;
if (ascot2e_sett[tv_system].agc_sel != ASCOT2E_AUTO) {
/* AGC pin setting from parameter table */
data[0] |= (u8)(
(ascot2e_sett[tv_system].agc_sel & 0x03) << 3);
}
if (ascot2e_sett[tv_system].if_out_sel != ASCOT2E_AUTO) {
/* IFOUT pin setting from parameter table */
data[0] |= (u8)(
(ascot2e_sett[tv_system].if_out_sel & 0x01) << 2);
}
/* Set bit[4:2] only */
ascot2e_set_reg_bits(priv, 0x05, data[0], 0x1c);
/* 0x06 - 0x0F */
/* REF_R setting (0x06) */
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8) {
/* xtal, xtal*2 */
data[0] = (frequency > 500000) ? 16 : 32;
} else {
/* xtal/8, xtal/4 */
data[0] = (frequency > 500000) ? 2 : 4;
}
/* XOSC_SEL=100uA */
data[1] = 0x04;
/* KBW setting (0x08), KC0 setting (0x09), KC1 setting (0x0A) */
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8) {
data[2] = 18;
data[3] = 120;
data[4] = 20;
} else {
data[2] = 48;
data[3] = 10;
data[4] = 30;
}
/* ORDER/R2_RANGE/R2_BANK/C2_BANK setting (0x0B) */
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8)
data[5] = (frequency > 500000) ? 0x08 : 0x0c;
else
data[5] = (frequency > 500000) ? 0x30 : 0x38;
/* Set MIX_OLL (0x0C) value from parameter table */
data[6] = ascot2e_sett[tv_system].mix_oll;
/* Set RF_GAIN (0x0D) setting from parameter table */
if (ascot2e_sett[tv_system].rf_gain == ASCOT2E_AUTO) {
/* RF_GAIN auto control enable */
ascot2e_write_reg(priv, 0x4E, 0x01);
/* RF_GAIN Default value */
data[7] = 0x00;
} else {
/* RF_GAIN auto control disable */
ascot2e_write_reg(priv, 0x4E, 0x00);
data[7] = ascot2e_sett[tv_system].rf_gain;
}
/* Set IF_BPF_GC/FIF_OFFSET (0x0E) value from parameter table */
data[8] = (u8)((ascot2e_sett[tv_system].fif_offset << 3) |
(ascot2e_sett[tv_system].if_bpf_gc & 0x07));
/* Set BW_OFFSET (0x0F) value from parameter table */
data[9] = ascot2e_sett[tv_system].bw_offset;
ascot2e_write_regs(priv, 0x06, data, 10);
/*
* 0x45 - 0x47
* LNA optimization setting
* RF_LNA_DIST1-5, RF_LNA_CM
*/
if (tv_system == ASCOT2E_DTV_DVBC_6 ||
tv_system == ASCOT2E_DTV_DVBC_8) {
data[0] = 0x0F;
data[1] = 0x00;
data[2] = 0x01;
} else {
data[0] = 0x0F;
data[1] = 0x00;
data[2] = 0x03;
}
ascot2e_write_regs(priv, 0x45, data, 3);
/* 0x49 - 0x4A
Set RF_OLDET_ENX/RF_OLDET_OLL value from parameter table */
data[0] = ascot2e_sett[tv_system].rf_oldet;
/* Set IF_BPF_F0 value from parameter table */
data[1] = ascot2e_sett[tv_system].if_bpf_f0;
ascot2e_write_regs(priv, 0x49, data, 2);
/*
* Tune now
* RFAGC fast mode / RFAGC auto control enable
* (set bit[7], bit[5:4] only)
* vco_cal = 1, set MIX_OL_CPU_EN
*/
ascot2e_set_reg_bits(priv, 0x0c, 0x90, 0xb0);
/* Logic wake up, CPU wake up */
data[0] = 0xc4;
data[1] = 0x40;
ascot2e_write_regs(priv, 0x03, data, 2);
/* 0x10 - 0x14 */
data[0] = (u8)(frequency & 0xFF); /* 0x10: FRF_L */
data[1] = (u8)((frequency >> 8) & 0xFF); /* 0x11: FRF_M */
data[2] = (u8)((frequency >> 16) & 0x0F); /* 0x12: FRF_H (bit[3:0]) */
/* 0x12: BW (bit[5:4]) */
data[2] |= (u8)(ascot2e_sett[tv_system].bw << 4);
data[3] = 0xFF; /* 0x13: VCO calibration enable */
data[4] = 0xFF; /* 0x14: Analog block enable */
/* Tune (Burst write) */
ascot2e_write_regs(priv, 0x10, data, 5);
msleep(50);
/* CPU deep sleep */
ascot2e_write_reg(priv, 0x04, 0x00);
/* Logic sleep */
ascot2e_write_reg(priv, 0x03, 0xC0);
/* RFAGC normal mode (set bit[5:4] only) */
ascot2e_set_reg_bits(priv, 0x0C, 0x00, 0x30);
priv->frequency = frequency;
return 0;
}
static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct ascot2e_priv *priv = fe->tuner_priv;
*frequency = priv->frequency * 1000;
return 0;
}
static struct dvb_tuner_ops ascot2e_tuner_ops = {
.info = {
.name = "Sony ASCOT2E",
.frequency_min = 1000000,
.frequency_max = 1200000000,
.frequency_step = 25000,
},
.init = ascot2e_init,
.release = ascot2e_release,
.sleep = ascot2e_sleep,
.set_params = ascot2e_set_params,
.get_frequency = ascot2e_get_frequency,
};
struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c)
{
u8 data[4];
struct ascot2e_priv *priv = NULL;
priv = kzalloc(sizeof(struct ascot2e_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->i2c_address = (config->i2c_address >> 1);
priv->i2c = i2c;
priv->set_tuner_data = config->set_tuner_priv;
priv->set_tuner = config->set_tuner_callback;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
/* 16 MHz xTal frequency */
data[0] = 16;
/* VCO current setting */
data[1] = 0x06;
/* Logic wake up, CPU boot */
data[2] = 0xC4;
data[3] = 0x40;
ascot2e_write_regs(priv, 0x01, data, 4);
/* RFVGA optimization setting (RF_DIST0 - RF_DIST2) */
data[0] = 0x10;
data[1] = 0x3F;
data[2] = 0x25;
ascot2e_write_regs(priv, 0x22, data, 3);
/* PLL mode setting */
ascot2e_write_reg(priv, 0x28, 0x1e);
/* RSSI setting */
ascot2e_write_reg(priv, 0x59, 0x04);
/* TODO check CPU HW error state here */
msleep(80);
/* Xtal oscillator current control setting */
ascot2e_write_reg(priv, 0x4c, 0x01);
/* XOSC_SEL=100uA */
ascot2e_write_reg(priv, 0x07, 0x04);
/* CPU deep sleep */
ascot2e_write_reg(priv, 0x04, 0x00);
/* Logic sleep */
ascot2e_write_reg(priv, 0x03, 0xc0);
/* Power save setting */
data[0] = 0x00;
data[1] = 0x04;
ascot2e_write_regs(priv, 0x14, data, 2);
ascot2e_write_reg(priv, 0x50, 0x01);
priv->state = STATE_SLEEP;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
memcpy(&fe->ops.tuner_ops, &ascot2e_tuner_ops,
sizeof(struct dvb_tuner_ops));
fe->tuner_priv = priv;
dev_info(&priv->i2c->dev,
"Sony ASCOT2E attached on addr=%x at I2C adapter %p\n",
priv->i2c_address, priv->i2c);
return fe;
}
EXPORT_SYMBOL(ascot2e_attach);
MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver");
MODULE_AUTHOR("[email protected]");
MODULE_LICENSE("GPL");

View file

@ -0,0 +1,58 @@
/*
* ascot2e.h
*
* Sony Ascot3E DVB-T/T2/C/C2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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.
*/
#ifndef __DVB_ASCOT2E_H__
#define __DVB_ASCOT2E_H__
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
/**
* struct ascot2e_config - the configuration of Ascot2E tuner driver
* @i2c_address: I2C address of the tuner
* @xtal_freq_mhz: Oscillator frequency, MHz
* @set_tuner_priv: Callback function private context
* @set_tuner_callback: Callback function that notifies the parent driver
* which tuner is active now
*/
struct ascot2e_config {
u8 i2c_address;
u8 xtal_freq_mhz;
void *set_tuner_priv;
int (*set_tuner_callback)(void *, int);
};
#if IS_REACHABLE(CONFIG_DVB_ASCOT2E)
extern struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
const struct ascot2e_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View file

@ -820,7 +820,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id);
static struct i2c_driver au8522_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "au8522",
},
.probe = au8522_probe,

View file

@ -1011,7 +1011,7 @@ static int cx24123_tune(struct dvb_frontend *fe,
static int cx24123_get_algo(struct dvb_frontend *fe)
{
return 1; /* FE_ALGO_HW */
return DVBFE_ALGO_HW;
}
static void cx24123_release(struct dvb_frontend *fe)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,65 @@
/*
* cxd2841er.h
*
* Sony CXD2441ER digital demodulator driver public definitions
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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.
*/
#ifndef CXD2841ER_H
#define CXD2841ER_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
struct cxd2841er_config {
u8 i2c_addr;
};
#if IS_REACHABLE(CONFIG_DVB_CXD2841ER)
extern struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
struct i2c_adapter *i2c);
extern struct dvb_frontend *cxd2841er_attach_t(struct cxd2841er_config *cfg,
struct i2c_adapter *i2c);
extern struct dvb_frontend *cxd2841er_attach_c(struct cxd2841er_config *cfg,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *cxd2841er_attach_s(
struct cxd2841er_config *cfg,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend *cxd2841er_attach_t(
struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend *cxd2841er_attach_c(
struct cxd2841er_config *cfg, struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View file

@ -0,0 +1,43 @@
/*
* cxd2841er_priv.h
*
* Sony CXD2441ER digital demodulator driver internal definitions
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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.
*/
#ifndef CXD2841ER_PRIV_H
#define CXD2841ER_PRIV_H
#define I2C_SLVX 0
#define I2C_SLVT 1
#define CXD2841ER_CHIP_ID 0xa7
#define CXD2841ER_DVBS_POLLING_INVL 10
struct cxd2841er_cnr_data {
u32 value;
int cnr_x1000;
};
enum cxd2841er_dvbt2_profile_t {
DVBT2_PROFILE_ANY = 0,
DVBT2_PROFILE_BASE = 1,
DVBT2_PROFILE_LITE = 2
};
#endif

View file

@ -34,7 +34,7 @@ struct dvb_pll_priv {
struct i2c_adapter *i2c;
/* the PLL descriptor */
struct dvb_pll_desc *pll_desc;
const struct dvb_pll_desc *pll_desc;
/* cached frequency/bandwidth */
u32 frequency;
@ -57,7 +57,7 @@ MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
/* ----------------------------------------------------------- */
struct dvb_pll_desc {
char *name;
const char *name;
u32 min;
u32 max;
u32 iffreq;
@ -71,13 +71,13 @@ struct dvb_pll_desc {
u32 stepsize;
u8 config;
u8 cb;
} entries[12];
} entries[];
};
/* ----------------------------------------------------------- */
/* descriptions */
static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
static const struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
.name = "Thomson dtt7579",
.min = 177000000,
.max = 858000000,
@ -99,7 +99,7 @@ static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x10;
}
static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
static const struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
.name = "Thomson dtt759x",
.min = 177000000,
.max = 896000000,
@ -123,7 +123,7 @@ static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] ^= 0x10;
}
static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
static const struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
.name = "Thomson dtt7520x",
.min = 185000000,
.max = 900000000,
@ -141,7 +141,7 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
},
};
static struct dvb_pll_desc dvb_pll_lg_z201 = {
static const struct dvb_pll_desc dvb_pll_lg_z201 = {
.name = "LG z201",
.min = 174000000,
.max = 862000000,
@ -157,7 +157,7 @@ static struct dvb_pll_desc dvb_pll_lg_z201 = {
},
};
static struct dvb_pll_desc dvb_pll_unknown_1 = {
static const struct dvb_pll_desc dvb_pll_unknown_1 = {
.name = "unknown 1", /* used by dntv live dvb-t */
.min = 174000000,
.max = 862000000,
@ -179,7 +179,7 @@ static struct dvb_pll_desc dvb_pll_unknown_1 = {
/* Infineon TUA6010XS
* used in Thomson Cable Tuner
*/
static struct dvb_pll_desc dvb_pll_tua6010xs = {
static const struct dvb_pll_desc dvb_pll_tua6010xs = {
.name = "Infineon TUA6010XS",
.min = 44250000,
.max = 858000000,
@ -193,7 +193,7 @@ static struct dvb_pll_desc dvb_pll_tua6010xs = {
};
/* Panasonic env57h1xd5 (some Philips PLL ?) */
static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
static const struct dvb_pll_desc dvb_pll_env57h1xd5 = {
.name = "Panasonic ENV57H1XD5",
.min = 44250000,
.max = 858000000,
@ -217,7 +217,7 @@ static void tda665x_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x08;
}
static struct dvb_pll_desc dvb_pll_tda665x = {
static const struct dvb_pll_desc dvb_pll_tda665x = {
.name = "Philips TDA6650/TDA6651",
.min = 44250000,
.max = 858000000,
@ -251,7 +251,7 @@ static void tua6034_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x08;
}
static struct dvb_pll_desc dvb_pll_tua6034 = {
static const struct dvb_pll_desc dvb_pll_tua6034 = {
.name = "Infineon TUA6034",
.min = 44250000,
.max = 858000000,
@ -275,7 +275,7 @@ static void tded4_bw(struct dvb_frontend *fe, u8 *buf)
buf[3] |= 0x04;
}
static struct dvb_pll_desc dvb_pll_tded4 = {
static const struct dvb_pll_desc dvb_pll_tded4 = {
.name = "ALPS TDED4",
.min = 47000000,
.max = 863000000,
@ -293,7 +293,7 @@ static struct dvb_pll_desc dvb_pll_tded4 = {
/* ALPS TDHU2
* used in AverTVHD MCE A180
*/
static struct dvb_pll_desc dvb_pll_tdhu2 = {
static const struct dvb_pll_desc dvb_pll_tdhu2 = {
.name = "ALPS TDHU2",
.min = 54000000,
.max = 864000000,
@ -310,7 +310,7 @@ static struct dvb_pll_desc dvb_pll_tdhu2 = {
/* Samsung TBMV30111IN / TBMV30712IN1
* used in Air2PC ATSC - 2nd generation (nxt2002)
*/
static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
static const struct dvb_pll_desc dvb_pll_samsung_tbmv = {
.name = "Samsung TBMV30111IN / TBMV30712IN1",
.min = 54000000,
.max = 860000000,
@ -329,7 +329,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
/*
* Philips SD1878 Tuner.
*/
static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
static const struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
.name = "Philips SD1878",
.min = 950000,
.max = 2150000,
@ -395,7 +395,7 @@ static void opera1_bw(struct dvb_frontend *fe, u8 *buf)
return;
}
static struct dvb_pll_desc dvb_pll_opera1 = {
static const struct dvb_pll_desc dvb_pll_opera1 = {
.name = "Opera Tuner",
.min = 900000,
.max = 2250000,
@ -442,7 +442,7 @@ static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf)
}
/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
static const struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
.name = "Samsung DTOS403IH102A",
.min = 44250000,
.max = 858000000,
@ -462,7 +462,7 @@ static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
};
/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
static const struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
.name = "Samsung TDTC9251DH0",
.min = 48000000,
.max = 863000000,
@ -476,7 +476,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
};
/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
static const struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
.name = "Samsung TBDU18132",
.min = 950000,
.max = 2150000, /* guesses */
@ -497,7 +497,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
};
/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
static const struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
.name = "Samsung TBMU24112",
.min = 950000,
.max = 2150000, /* guesses */
@ -518,7 +518,7 @@ static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
* 153 - 430 0 * 0 0 0 0 1 0 0x02
* 430 - 822 0 * 0 0 1 0 0 0 0x08
* 822 - 862 1 * 0 0 1 0 0 0 0x88 */
static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
static const struct dvb_pll_desc dvb_pll_alps_tdee4 = {
.name = "ALPS TDEE4",
.min = 47000000,
.max = 862000000,
@ -534,7 +534,7 @@ static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
/* ----------------------------------------------------------- */
static struct dvb_pll_desc *pll_list[] = {
static const struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_UNDEFINED] = NULL,
[DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579,
[DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x,
@ -564,7 +564,7 @@ static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
const u32 frequency)
{
struct dvb_pll_priv *priv = fe->tuner_priv;
struct dvb_pll_desc *desc = priv->pll_desc;
const struct dvb_pll_desc *desc = priv->pll_desc;
u32 div;
int i;
@ -758,7 +758,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
.buf = b1, .len = 1 };
struct dvb_pll_priv *priv = NULL;
int ret;
struct dvb_pll_desc *desc;
const struct dvb_pll_desc *desc;
if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
(id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))

View file

@ -0,0 +1,430 @@
/*
* horus3a.h
*
* Sony Horus3A DVB-S/S2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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/slab.h>
#include <linux/module.h>
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "horus3a.h"
#include "dvb_frontend.h"
#define MAX_WRITE_REGSIZE 5
enum horus3a_state {
STATE_UNKNOWN,
STATE_SLEEP,
STATE_ACTIVE
};
struct horus3a_priv {
u32 frequency;
u8 i2c_address;
struct i2c_adapter *i2c;
enum horus3a_state state;
void *set_tuner_data;
int (*set_tuner)(void *, int);
};
static void horus3a_i2c_debug(struct horus3a_priv *priv,
u8 reg, u8 write, const u8 *data, u32 len)
{
dev_dbg(&priv->i2c->dev, "horus3a: I2C %s reg 0x%02x size %d\n",
(write == 0 ? "read" : "write"), reg, len);
print_hex_dump_bytes("horus3a: I2C data: ",
DUMP_PREFIX_OFFSET, data, len);
}
static int horus3a_write_regs(struct horus3a_priv *priv,
u8 reg, const u8 *data, u32 len)
{
int ret;
u8 buf[MAX_WRITE_REGSIZE + 1];
struct i2c_msg msg[1] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = len + 1,
.buf = buf,
}
};
if (len + 1 >= sizeof(buf)) {
dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
reg, len + 1);
return -E2BIG;
}
horus3a_i2c_debug(priv, reg, 1, data, len);
buf[0] = reg;
memcpy(&buf[1], data, len);
ret = i2c_transfer(priv->i2c, msg, 1);
if (ret >= 0 && ret != 1)
ret = -EREMOTEIO;
if (ret < 0) {
dev_warn(&priv->i2c->dev,
"%s: i2c wr failed=%d reg=%02x len=%d\n",
KBUILD_MODNAME, ret, reg, len);
return ret;
}
return 0;
}
static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
{
return horus3a_write_regs(priv, reg, &val, 1);
}
static int horus3a_enter_power_save(struct horus3a_priv *priv)
{
u8 data[2];
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_SLEEP)
return 0;
/* IQ Generator disable */
horus3a_write_reg(priv, 0x2a, 0x79);
/* MDIV_EN = 0 */
horus3a_write_reg(priv, 0x29, 0x70);
/* VCO disable preparation */
horus3a_write_reg(priv, 0x28, 0x3e);
/* VCO buffer disable */
horus3a_write_reg(priv, 0x2a, 0x19);
/* VCO calibration disable */
horus3a_write_reg(priv, 0x1c, 0x00);
/* Power save setting (xtal is not stopped) */
data[0] = 0xC0;
/* LNA is Disabled */
data[1] = 0xA7;
/* 0x11 - 0x12 */
horus3a_write_regs(priv, 0x11, data, sizeof(data));
priv->state = STATE_SLEEP;
return 0;
}
static int horus3a_leave_power_save(struct horus3a_priv *priv)
{
u8 data[2];
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
if (priv->state == STATE_ACTIVE)
return 0;
/* Leave power save */
data[0] = 0x00;
/* LNA is Disabled */
data[1] = 0xa7;
/* 0x11 - 0x12 */
horus3a_write_regs(priv, 0x11, data, sizeof(data));
/* VCO buffer enable */
horus3a_write_reg(priv, 0x2a, 0x79);
/* VCO calibration enable */
horus3a_write_reg(priv, 0x1c, 0xc0);
/* MDIV_EN = 1 */
horus3a_write_reg(priv, 0x29, 0x71);
usleep_range(5000, 7000);
priv->state = STATE_ACTIVE;
return 0;
}
static int horus3a_init(struct dvb_frontend *fe)
{
struct horus3a_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
return 0;
}
static int horus3a_release(struct dvb_frontend *fe)
{
struct horus3a_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
kfree(fe->tuner_priv);
fe->tuner_priv = NULL;
return 0;
}
static int horus3a_sleep(struct dvb_frontend *fe)
{
struct horus3a_priv *priv = fe->tuner_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
horus3a_enter_power_save(priv);
return 0;
}
static int horus3a_set_params(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
struct horus3a_priv *priv = fe->tuner_priv;
u32 frequency = p->frequency;
u32 symbol_rate = p->symbol_rate/1000;
u8 mixdiv = 0;
u8 mdiv = 0;
u32 ms = 0;
u8 f_ctl = 0;
u8 g_ctl = 0;
u8 fc_lpf = 0;
u8 data[5];
dev_dbg(&priv->i2c->dev, "%s(): frequency %dkHz symbol_rate %dksps\n",
__func__, frequency, symbol_rate);
if (priv->set_tuner)
priv->set_tuner(priv->set_tuner_data, 0);
if (priv->state == STATE_SLEEP)
horus3a_leave_power_save(priv);
/* frequency should be X MHz (X : integer) */
frequency = DIV_ROUND_CLOSEST(frequency, 1000) * 1000;
if (frequency <= 1155000) {
mixdiv = 4;
mdiv = 1;
} else {
mixdiv = 2;
mdiv = 0;
}
/* Assumed that fREF == 1MHz (1000kHz) */
ms = DIV_ROUND_CLOSEST((frequency * mixdiv) / 2, 1000);
if (ms > 0x7FFF) { /* 15 bit */
dev_err(&priv->i2c->dev, "horus3a: invalid frequency %d\n",
frequency);
return -EINVAL;
}
if (frequency < 975000) {
/* F_CTL=11100 G_CTL=001 */
f_ctl = 0x1C;
g_ctl = 0x01;
} else if (frequency < 1050000) {
/* F_CTL=11000 G_CTL=010 */
f_ctl = 0x18;
g_ctl = 0x02;
} else if (frequency < 1150000) {
/* F_CTL=10100 G_CTL=010 */
f_ctl = 0x14;
g_ctl = 0x02;
} else if (frequency < 1250000) {
/* F_CTL=10000 G_CTL=011 */
f_ctl = 0x10;
g_ctl = 0x03;
} else if (frequency < 1350000) {
/* F_CTL=01100 G_CTL=100 */
f_ctl = 0x0C;
g_ctl = 0x04;
} else if (frequency < 1450000) {
/* F_CTL=01010 G_CTL=100 */
f_ctl = 0x0A;
g_ctl = 0x04;
} else if (frequency < 1600000) {
/* F_CTL=00111 G_CTL=101 */
f_ctl = 0x07;
g_ctl = 0x05;
} else if (frequency < 1800000) {
/* F_CTL=00100 G_CTL=010 */
f_ctl = 0x04;
g_ctl = 0x02;
} else if (frequency < 2000000) {
/* F_CTL=00010 G_CTL=001 */
f_ctl = 0x02;
g_ctl = 0x01;
} else {
/* F_CTL=00000 G_CTL=000 */
f_ctl = 0x00;
g_ctl = 0x00;
}
/* LPF cutoff frequency setting */
if (p->delivery_system == SYS_DVBS) {
/*
* rolloff = 0.35
* SR <= 4.3
* fc_lpf = 5
* 4.3 < SR <= 10
* fc_lpf = SR * (1 + rolloff) / 2 + SR / 2 =
* SR * 1.175 = SR * (47/40)
* 10 < SR
* fc_lpf = SR * (1 + rolloff) / 2 + 5 =
* SR * 0.675 + 5 = SR * (27/40) + 5
* NOTE: The result should be round up.
*/
if (symbol_rate <= 4300)
fc_lpf = 5;
else if (symbol_rate <= 10000)
fc_lpf = (u8)DIV_ROUND_UP(symbol_rate * 47, 40000);
else
fc_lpf = (u8)DIV_ROUND_UP(symbol_rate * 27, 40000) + 5;
/* 5 <= fc_lpf <= 36 */
if (fc_lpf > 36)
fc_lpf = 36;
} else if (p->delivery_system == SYS_DVBS2) {
int rolloff;
switch (p->rolloff) {
case ROLLOFF_35:
rolloff = 35;
break;
case ROLLOFF_25:
rolloff = 25;
break;
case ROLLOFF_20:
rolloff = 20;
break;
case ROLLOFF_AUTO:
default:
dev_err(&priv->i2c->dev,
"horus3a: auto roll-off is not supported\n");
return -EINVAL;
}
/*
* SR <= 4.5:
* fc_lpf = 5
* 4.5 < SR <= 10:
* fc_lpf = SR * (1 + rolloff) / 2 + SR / 2
* 10 < SR:
* fc_lpf = SR * (1 + rolloff) / 2 + 5
* NOTE: The result should be round up.
*/
if (symbol_rate <= 4500)
fc_lpf = 5;
else if (symbol_rate <= 10000)
fc_lpf = (u8)DIV_ROUND_UP(
symbol_rate * (200 + rolloff), 200000);
else
fc_lpf = (u8)DIV_ROUND_UP(
symbol_rate * (100 + rolloff), 200000) + 5;
/* 5 <= fc_lpf <= 36 is valid */
if (fc_lpf > 36)
fc_lpf = 36;
} else {
dev_err(&priv->i2c->dev,
"horus3a: invalid delivery system %d\n",
p->delivery_system);
return -EINVAL;
}
/* 0x00 - 0x04 */
data[0] = (u8)((ms >> 7) & 0xFF);
data[1] = (u8)((ms << 1) & 0xFF);
data[2] = 0x00;
data[3] = 0x00;
data[4] = (u8)(mdiv << 7);
horus3a_write_regs(priv, 0x00, data, sizeof(data));
/* Write G_CTL, F_CTL */
horus3a_write_reg(priv, 0x09, (u8)((g_ctl << 5) | f_ctl));
/* Write LPF cutoff frequency */
horus3a_write_reg(priv, 0x37, (u8)(0x80 | (fc_lpf << 1)));
/* Start Calibration */
horus3a_write_reg(priv, 0x05, 0x80);
/* IQ Generator enable */
horus3a_write_reg(priv, 0x2a, 0x7b);
/* tuner stabilization time */
msleep(60);
/* Store tuned frequency to the struct */
priv->frequency = ms * 2 * 1000 / mixdiv;
return 0;
}
static int horus3a_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct horus3a_priv *priv = fe->tuner_priv;
*frequency = priv->frequency;
return 0;
}
static struct dvb_tuner_ops horus3a_tuner_ops = {
.info = {
.name = "Sony Horus3a",
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_step = 1000,
},
.init = horus3a_init,
.release = horus3a_release,
.sleep = horus3a_sleep,
.set_params = horus3a_set_params,
.get_frequency = horus3a_get_frequency,
};
struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
const struct horus3a_config *config,
struct i2c_adapter *i2c)
{
u8 buf[3], val;
struct horus3a_priv *priv = NULL;
priv = kzalloc(sizeof(struct horus3a_priv), GFP_KERNEL);
if (priv == NULL)
return NULL;
priv->i2c_address = (config->i2c_address >> 1);
priv->i2c = i2c;
priv->set_tuner_data = config->set_tuner_priv;
priv->set_tuner = config->set_tuner_callback;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
/* wait 4ms after power on */
usleep_range(4000, 6000);
/* IQ Generator disable */
horus3a_write_reg(priv, 0x2a, 0x79);
/* REF_R = Xtal Frequency */
buf[0] = config->xtal_freq_mhz;
buf[1] = config->xtal_freq_mhz;
buf[2] = 0;
/* 0x6 - 0x8 */
horus3a_write_regs(priv, 0x6, buf, 3);
/* IQ Out = Single Ended */
horus3a_write_reg(priv, 0x0a, 0x40);
switch (config->xtal_freq_mhz) {
case 27:
val = 0x1f;
break;
case 24:
val = 0x10;
break;
case 16:
val = 0xc;
break;
default:
val = 0;
dev_warn(&priv->i2c->dev,
"horus3a: invalid xtal frequency %dMHz\n",
config->xtal_freq_mhz);
break;
}
val <<= 2;
horus3a_write_reg(priv, 0x0e, val);
horus3a_enter_power_save(priv);
usleep_range(3000, 5000);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
memcpy(&fe->ops.tuner_ops, &horus3a_tuner_ops,
sizeof(struct dvb_tuner_ops));
fe->tuner_priv = priv;
dev_info(&priv->i2c->dev,
"Sony HORUS3A attached on addr=%x at I2C adapter %p\n",
priv->i2c_address, priv->i2c);
return fe;
}
EXPORT_SYMBOL(horus3a_attach);
MODULE_DESCRIPTION("Sony HORUS3A sattelite tuner driver");
MODULE_AUTHOR("Sergey Kozlov <[email protected]>");
MODULE_LICENSE("GPL");

View file

@ -0,0 +1,58 @@
/*
* horus3a.h
*
* Sony Horus3A DVB-S/S2 tuner driver
*
* Copyright 2012 Sony Corporation
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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.
*/
#ifndef __DVB_HORUS3A_H__
#define __DVB_HORUS3A_H__
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
/**
* struct horus3a_config - the configuration of Horus3A tuner driver
* @i2c_address: I2C address of the tuner
* @xtal_freq_mhz: Oscillator frequency, MHz
* @set_tuner_priv: Callback function private context
* @set_tuner_callback: Callback function that notifies the parent driver
* which tuner is active now
*/
struct horus3a_config {
u8 i2c_address;
u8 xtal_freq_mhz;
void *set_tuner_priv;
int (*set_tuner_callback)(void *, int);
};
#if IS_REACHABLE(CONFIG_DVB_HORUS3A)
extern struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe,
const struct horus3a_config *config,
struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *horus3a_attach(
const struct cxd2820r_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View file

@ -0,0 +1,189 @@
/*
* lnbh25.c
*
* Driver for LNB supply and control IC LNBH25
*
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include "dvb_frontend.h"
#include "lnbh25.h"
/**
* struct lnbh25_priv - LNBH25 driver private data
* @i2c: pointer to the I2C adapter structure
* @i2c_address: I2C address of LNBH25 SEC chip
* @config: Registers configuration:
* offset 0: 1st register address, always 0x02 (DATA1)
* offset 1: DATA1 register value
* offset 2: DATA2 register value
*/
struct lnbh25_priv {
struct i2c_adapter *i2c;
u8 i2c_address;
u8 config[3];
};
#define LNBH25_STATUS_OFL 0x1
#define LNBH25_STATUS_VMON 0x4
#define LNBH25_VSEL_13 0x03
#define LNBH25_VSEL_18 0x0a
static int lnbh25_read_vmon(struct lnbh25_priv *priv)
{
int i, ret;
u8 addr = 0x00;
u8 status[6];
struct i2c_msg msg[2] = {
{
.addr = priv->i2c_address,
.flags = 0,
.len = 1,
.buf = &addr
}, {
.addr = priv->i2c_address,
.flags = I2C_M_RD,
.len = sizeof(status),
.buf = status
}
};
for (i = 0; i < 2; i++) {
ret = i2c_transfer(priv->i2c, &msg[i], 1);
if (ret >= 0 && ret != 1)
ret = -EIO;
if (ret < 0) {
dev_dbg(&priv->i2c->dev,
"%s(): I2C transfer %d failed (%d)\n",
__func__, i, ret);
return ret;
}
}
print_hex_dump_bytes("lnbh25_read_vmon: ",
DUMP_PREFIX_OFFSET, status, sizeof(status));
if ((status[0] & (LNBH25_STATUS_OFL | LNBH25_STATUS_VMON)) != 0) {
dev_err(&priv->i2c->dev,
"%s(): voltage in failure state, status reg 0x%x\n",
__func__, status[0]);
return -EIO;
}
return 0;
}
static int lnbh25_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage voltage)
{
int ret;
u8 data1_reg;
const char *vsel;
struct lnbh25_priv *priv = fe->sec_priv;
struct i2c_msg msg = {
.addr = priv->i2c_address,
.flags = 0,
.len = sizeof(priv->config),
.buf = priv->config
};
switch (voltage) {
case SEC_VOLTAGE_OFF:
data1_reg = 0x00;
vsel = "Off";
break;
case SEC_VOLTAGE_13:
data1_reg = LNBH25_VSEL_13;
vsel = "13V";
break;
case SEC_VOLTAGE_18:
data1_reg = LNBH25_VSEL_18;
vsel = "18V";
break;
default:
return -EINVAL;
}
priv->config[1] = data1_reg;
dev_dbg(&priv->i2c->dev,
"%s(): %s, I2C 0x%x write [ %02x %02x %02x ]\n",
__func__, vsel, priv->i2c_address,
priv->config[0], priv->config[1], priv->config[2]);
ret = i2c_transfer(priv->i2c, &msg, 1);
if (ret >= 0 && ret != 1)
ret = -EIO;
if (ret < 0) {
dev_err(&priv->i2c->dev, "%s(): I2C transfer error (%d)\n",
__func__, ret);
return ret;
}
if (voltage != SEC_VOLTAGE_OFF) {
msleep(120);
ret = lnbh25_read_vmon(priv);
} else {
msleep(20);
ret = 0;
}
return ret;
}
static void lnbh25_release(struct dvb_frontend *fe)
{
struct lnbh25_priv *priv = fe->sec_priv;
dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
lnbh25_set_voltage(fe, SEC_VOLTAGE_OFF);
kfree(fe->sec_priv);
fe->sec_priv = NULL;
}
struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c)
{
struct lnbh25_priv *priv;
dev_dbg(&i2c->dev, "%s()\n", __func__);
priv = kzalloc(sizeof(struct lnbh25_priv), GFP_KERNEL);
if (!priv)
return NULL;
priv->i2c_address = (cfg->i2c_address >> 1);
priv->i2c = i2c;
priv->config[0] = 0x02;
priv->config[1] = 0x00;
priv->config[2] = cfg->data2_config;
fe->sec_priv = priv;
if (lnbh25_set_voltage(fe, SEC_VOLTAGE_OFF)) {
dev_err(&i2c->dev,
"%s(): no LNBH25 found at I2C addr 0x%02x\n",
__func__, priv->i2c_address);
kfree(priv);
fe->sec_priv = NULL;
return NULL;
}
fe->ops.release_sec = lnbh25_release;
fe->ops.set_voltage = lnbh25_set_voltage;
dev_err(&i2c->dev, "%s(): attached at I2C addr 0x%02x\n",
__func__, priv->i2c_address);
return fe;
}
EXPORT_SYMBOL(lnbh25_attach);
MODULE_DESCRIPTION("ST LNBH25 driver");
MODULE_AUTHOR("[email protected]");
MODULE_LICENSE("GPL");

View file

@ -0,0 +1,56 @@
/*
* lnbh25.c
*
* Driver for LNB supply and control IC LNBH25
*
* Copyright (C) 2014 NetUP Inc.
* Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
* Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
*
* 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.
*/
#ifndef LNBH25_H
#define LNBH25_H
#include <linux/i2c.h>
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
/* 22 kHz tone enabled. Tone output controlled by DSQIN pin */
#define LNBH25_TEN 0x01
/* Low power mode activated (used only with 22 kHz tone output disabled) */
#define LNBH25_LPM 0x02
/* DSQIN input pin is set to receive external 22 kHz TTL signal source */
#define LNBH25_EXTM 0x04
struct lnbh25_config {
u8 i2c_address;
u8 data2_config;
};
#if IS_REACHABLE(CONFIG_DVB_LNBH25)
struct dvb_frontend *lnbh25_attach(
struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c);
#else
static inline dvb_frontend *lnbh25_attach(
struct dvb_frontend *fe,
struct lnbh25_config *cfg,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif

View file

@ -1495,7 +1495,6 @@ MODULE_DEVICE_TABLE(i2c, m88ds3103_id_table);
static struct i2c_driver m88ds3103_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "m88ds3103",
.suppress_bind_attrs = true,
},

View file

@ -915,7 +915,6 @@ MODULE_DEVICE_TABLE(i2c, rtl2830_id_table);
static struct i2c_driver rtl2830_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "rtl2830",
},
.probe = rtl2830_probe,

View file

@ -1319,7 +1319,6 @@ MODULE_DEVICE_TABLE(i2c, rtl2832_id_table);
static struct i2c_driver rtl2832_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "rtl2832",
},
.probe = rtl2832_probe,

View file

@ -1538,7 +1538,6 @@ static int rtl2832_sdr_remove(struct platform_device *pdev)
static struct platform_driver rtl2832_sdr_driver = {
.driver = {
.name = "rtl2832_sdr",
.owner = THIS_MODULE,
},
.probe = rtl2832_sdr_probe,
.remove = rtl2832_sdr_remove,

View file

@ -466,7 +466,7 @@ static int s921_tune(struct dvb_frontend *fe,
static int s921_get_algo(struct dvb_frontend *fe)
{
return 1; /* FE_ALGO_HW */
return DVBFE_ALGO_HW;
}
static void s921_release(struct dvb_frontend *fe)

View file

@ -757,7 +757,6 @@ MODULE_DEVICE_TABLE(i2c, si2168_id_table);
static struct i2c_driver si2168_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "si2168",
},
.probe = si2168_probe,

View file

@ -426,7 +426,6 @@ MODULE_DEVICE_TABLE(i2c, sp2_id);
static struct i2c_driver sp2_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "sp2",
},
.probe = sp2_probe,

View file

@ -791,11 +791,13 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
memcpy(buf + 2, data, len);
if (i2cdebug)
printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
state->config->demod_address, reg, buf[2]);
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
printk(KERN_ERR "%s: i2c write error!\n", __func__);
printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n",
__func__, state->config->demod_address, reg, buf[2]);
return (ret != 1) ? -EREMOTEIO : 0;
}
@ -829,10 +831,12 @@ static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
printk(KERN_ERR "%s: i2c read error\n", __func__);
printk(KERN_ERR "%s: i2c read error ([%02x] %02x: %02x)\n",
__func__, state->config->demod_address, reg, b1[0]);
if (i2cdebug)
printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
state->config->demod_address, reg, b1[0]);
return b1[0];
}
@ -1550,6 +1554,11 @@ static int stv0367ter_init(struct dvb_frontend *fe)
switch (state->config->xtal) {
/*set internal freq to 53.125MHz */
case 16000000:
stv0367_writereg(state, R367TER_PLLMDIV, 0x2);
stv0367_writereg(state, R367TER_PLLNDIV, 0x1b);
stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
break;
case 25000000:
stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
stv0367_writereg(state, R367TER_PLLNDIV, 0x55);

File diff suppressed because it is too large Load diff

View file

@ -21,12 +21,11 @@
#ifndef TDA10071_H
#define TDA10071_H
#include <linux/kconfig.h>
#include <linux/dvb/frontend.h>
/*
* I2C address
* 0x55,
* 0x05, 0x55,
*/
/**
@ -53,64 +52,4 @@ struct tda10071_platform_data {
struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *);
};
struct tda10071_config {
/* Demodulator I2C address.
* Default: none, must set
* Values: 0x55,
*/
u8 demod_i2c_addr;
/* Tuner I2C address.
* Default: none, must set
* Values: 0x14, 0x54, ...
*/
u8 tuner_i2c_addr;
/* Max bytes I2C provider can write at once.
* Note: Buffer is taken from the stack currently!
* Default: none, must set
* Values:
*/
u16 i2c_wr_max;
/* TS output mode.
* Default: TDA10071_TS_SERIAL
* Values:
*/
#define TDA10071_TS_SERIAL 0
#define TDA10071_TS_PARALLEL 1
u8 ts_mode;
/* Input spectrum inversion.
* Default: 0
* Values: 0, 1
*/
bool spec_inv;
/* Xtal frequency Hz
* Default: none, must set
* Values:
*/
u32 xtal;
/* PLL multiplier.
* Default: none, must set
* Values:
*/
u8 pll_multiplier;
};
#if IS_REACHABLE(CONFIG_DVB_TDA10071)
extern struct dvb_frontend *tda10071_attach(
const struct tda10071_config *config, struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend *tda10071_attach(
const struct tda10071_config *config, struct i2c_adapter *i2c)
{
dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* TDA10071_H */

View file

@ -24,19 +24,27 @@
#include "dvb_frontend.h"
#include "tda10071.h"
#include <linux/firmware.h>
#include <linux/regmap.h>
struct tda10071_priv {
struct i2c_adapter *i2c;
struct tda10071_dev {
struct dvb_frontend fe;
struct i2c_client *client;
struct tda10071_config cfg;
struct regmap *regmap;
struct mutex cmd_execute_mutex;
u32 clk;
u16 i2c_wr_max;
u8 ts_mode;
bool spec_inv;
u8 pll_multiplier;
u8 tuner_i2c_addr;
u8 meas_count[2];
u32 ber;
u32 ucb;
u8 meas_count;
u32 dvbv3_ber;
enum fe_status fe_status;
enum fe_delivery_system delivery_system;
bool warm; /* FW running */
u64 post_bit_error;
u64 block_error;
};
static struct tda10071_modcod {

View file

@ -726,7 +726,6 @@ MODULE_DEVICE_TABLE(i2c, ts2020_id_table);
static struct i2c_driver ts2020_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ts2020",
},
.probe = ts2020_probe,

View file

@ -22,7 +22,7 @@ config VIDEO_IR_I2C
#
menu "Encoders, decoders, sensors and other helper chips"
visible if !MEDIA_SUBDRV_AUTOSELECT
visible if !MEDIA_SUBDRV_AUTOSELECT || COMPILE_TEST
comment "Audio decoders, processors and mixers"
@ -196,7 +196,8 @@ config VIDEO_ADV7183
config VIDEO_ADV7604
tristate "Analog Devices ADV7604 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && GPIOLIB
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
depends on GPIOLIB || COMPILE_TEST
select HDMI
---help---
Support for the Analog Devices ADV7604 video decoder.
@ -286,6 +287,16 @@ config VIDEO_SAA711X
To compile this driver as a module, choose M here: the
module will be called saa7115.
config VIDEO_TC358743
tristate "Toshiba TC358743 decoder"
depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
select HDMI
---help---
Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge.
To compile this driver as a module, choose M here: the
module will be called tc358743.
config VIDEO_TVP514X
tristate "Texas Instruments TVP514x video decoder"
depends on VIDEO_V4L2 && I2C

View file

@ -78,3 +78,4 @@ obj-$(CONFIG_VIDEO_AK881X) += ak881x.o
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_OV2659) += ov2659.o
obj-$(CONFIG_VIDEO_TC358743) += tc358743.o

View file

@ -401,7 +401,6 @@ MODULE_DEVICE_TABLE(i2c, adv7170_id);
static struct i2c_driver adv7170_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7170",
},
.probe = adv7170_probe,

View file

@ -455,7 +455,6 @@ MODULE_DEVICE_TABLE(i2c, adv7175_id);
static struct i2c_driver adv7175_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7175",
},
.probe = adv7175_probe,

View file

@ -25,6 +25,7 @@
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <media/v4l2-ioctl.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
@ -1324,11 +1325,20 @@ static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume);
#define ADV7180_PM_OPS NULL
#endif
#ifdef CONFIG_OF
static const struct of_device_id adv7180_of_id[] = {
{ .compatible = "adi,adv7180", },
{ },
};
MODULE_DEVICE_TABLE(of, adv7180_of_id);
#endif
static struct i2c_driver adv7180_driver = {
.driver = {
.owner = THIS_MODULE,
.name = KBUILD_MODNAME,
.pm = ADV7180_PM_OPS,
.of_match_table = of_match_ptr(adv7180_of_id),
},
.probe = adv7180_probe,
.remove = adv7180_remove,

View file

@ -319,13 +319,6 @@ static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv7343_core_ops = {
.log_status = adv7343_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
@ -529,7 +522,6 @@ MODULE_DEVICE_TABLE(of, adv7343_of_match);
static struct i2c_driver adv7343_driver = {
.driver = {
.of_match_table = of_match_ptr(adv7343_of_match),
.owner = THIS_MODULE,
.name = "adv7343",
},
.probe = adv7343_probe,

View file

@ -306,13 +306,6 @@ static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv7393_core_ops = {
.log_status = adv7393_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static int adv7393_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)

View file

@ -40,7 +40,7 @@ MODULE_PARM_DESC(debug, "debug level (0-2)");
MODULE_DESCRIPTION("Analog Devices ADV7511 HDMI Transmitter Device Driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
#define MASK_ADV7511_EDID_RDY_INT 0x04
#define MASK_ADV7511_MSEN_INT 0x40
@ -1576,7 +1576,6 @@ MODULE_DEVICE_TABLE(i2c, adv7511_id);
static struct i2c_driver adv7511_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7511",
},
.probe = adv7511_probe,

View file

@ -37,10 +37,12 @@
#include <linux/v4l2-dv-timings.h>
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <linux/regmap.h>
#include <media/adv7604.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-dv-timings.h>
#include <media/v4l2-of.h>
@ -81,6 +83,7 @@ MODULE_LICENSE("GPL");
enum adv76xx_type {
ADV7604,
ADV7611,
ADV7612,
};
struct adv76xx_reg_seq {
@ -188,6 +191,9 @@ struct adv76xx_state {
/* i2c clients */
struct i2c_client *i2c_clients[ADV76XX_PAGE_MAX];
/* Regmaps */
struct regmap *regmap[ADV76XX_PAGE_MAX];
/* controls */
struct v4l2_ctrl *detect_tx_5v_ctrl;
struct v4l2_ctrl *analog_sampling_phase_ctrl;
@ -373,66 +379,39 @@ static inline unsigned vtotal(const struct v4l2_bt_timings *t)
/* ----------------------------------------------------------------------- */
static s32 adv_smbus_read_byte_data_check(struct i2c_client *client,
u8 command, bool check)
static int adv76xx_read_check(struct adv76xx_state *state,
int client_page, u8 reg)
{
union i2c_smbus_data data;
if (!i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_READ, command,
I2C_SMBUS_BYTE_DATA, &data))
return data.byte;
if (check)
v4l_err(client, "error reading %02x, %02x\n",
client->addr, command);
return -EIO;
}
static s32 adv_smbus_read_byte_data(struct adv76xx_state *state,
enum adv76xx_page page, u8 command)
{
return adv_smbus_read_byte_data_check(state->i2c_clients[page],
command, true);
}
static s32 adv_smbus_write_byte_data(struct adv76xx_state *state,
enum adv76xx_page page, u8 command,
u8 value)
{
struct i2c_client *client = state->i2c_clients[page];
union i2c_smbus_data data;
struct i2c_client *client = state->i2c_clients[client_page];
int err;
int i;
unsigned int val;
data.byte = value;
for (i = 0; i < 3; i++) {
err = i2c_smbus_xfer(client->adapter, client->addr,
client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, &data);
if (!err)
break;
err = regmap_read(state->regmap[client_page], reg, &val);
if (err) {
v4l_err(client, "error reading %02x, %02x\n",
client->addr, reg);
return err;
}
if (err < 0)
v4l_err(client, "error writing %02x, %02x, %02x\n",
client->addr, command, value);
return err;
return val;
}
static s32 adv_smbus_write_i2c_block_data(struct adv76xx_state *state,
enum adv76xx_page page, u8 command,
unsigned length, const u8 *values)
/* adv76xx_write_block(): Write raw data with a maximum of I2C_SMBUS_BLOCK_MAX
* size to one or more registers.
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
static int adv76xx_write_block(struct adv76xx_state *state, int client_page,
unsigned int init_reg, const void *val,
size_t val_len)
{
struct i2c_client *client = state->i2c_clients[page];
union i2c_smbus_data data;
struct regmap *regmap = state->regmap[client_page];
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
data.block[0] = length;
memcpy(data.block + 1, values, length);
return i2c_smbus_xfer(client->adapter, client->addr, client->flags,
I2C_SMBUS_WRITE, command,
I2C_SMBUS_I2C_BLOCK_DATA, &data);
if (val_len > I2C_SMBUS_BLOCK_MAX)
val_len = I2C_SMBUS_BLOCK_MAX;
return regmap_raw_write(regmap, init_reg, val, val_len);
}
/* ----------------------------------------------------------------------- */
@ -441,14 +420,14 @@ static inline int io_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_IO, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_IO, reg);
}
static inline int io_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_IO, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_IO], reg, val);
}
static inline int io_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -460,71 +439,70 @@ static inline int avlink_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV7604_PAGE_AVLINK, reg);
return adv76xx_read_check(state, ADV7604_PAGE_AVLINK, reg);
}
static inline int avlink_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV7604_PAGE_AVLINK, reg, val);
return regmap_write(state->regmap[ADV7604_PAGE_AVLINK], reg, val);
}
static inline int cec_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_CEC, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_CEC, reg);
}
static inline int cec_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_CEC, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_CEC], reg, val);
}
static inline int infoframe_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_INFOFRAME, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_INFOFRAME, reg);
}
static inline int infoframe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_INFOFRAME,
reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_INFOFRAME], reg, val);
}
static inline int afe_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_AFE, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_AFE, reg);
}
static inline int afe_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_AFE, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_AFE], reg, val);
}
static inline int rep_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_REP, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_REP, reg);
}
static inline int rep_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_REP, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_REP], reg, val);
}
static inline int rep_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -536,28 +514,37 @@ static inline int edid_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_EDID, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_EDID, reg);
}
static inline int edid_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_EDID, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_EDID], reg, val);
}
static inline int edid_write_block(struct v4l2_subdev *sd,
unsigned len, const u8 *val)
unsigned int total_len, const u8 *val)
{
struct adv76xx_state *state = to_state(sd);
int err = 0;
int i;
int i = 0;
int len = 0;
v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n", __func__, len);
v4l2_dbg(2, debug, sd, "%s: write EDID block (%d byte)\n",
__func__, total_len);
while (!err && i < total_len) {
len = (total_len - i) > I2C_SMBUS_BLOCK_MAX ?
I2C_SMBUS_BLOCK_MAX :
(total_len - i);
err = adv76xx_write_block(state, ADV76XX_PAGE_EDID,
i, val + i, len);
i += len;
}
for (i = 0; !err && i < len; i += I2C_SMBUS_BLOCK_MAX)
err = adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_EDID,
i, I2C_SMBUS_BLOCK_MAX, val + i);
return err;
}
@ -587,7 +574,7 @@ static inline int hdmi_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_HDMI, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_HDMI, reg);
}
static u16 hdmi_read16(struct v4l2_subdev *sd, u8 reg, u16 mask)
@ -599,7 +586,7 @@ static inline int hdmi_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_HDMI, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_HDMI], reg, val);
}
static inline int hdmi_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -611,14 +598,14 @@ static inline int test_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_TEST, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_TEST], reg, val);
}
static inline int cp_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV76XX_PAGE_CP, reg);
return adv76xx_read_check(state, ADV76XX_PAGE_CP, reg);
}
static u16 cp_read16(struct v4l2_subdev *sd, u8 reg, u16 mask)
@ -630,7 +617,7 @@ static inline int cp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV76XX_PAGE_CP, reg, val);
return regmap_write(state->regmap[ADV76XX_PAGE_CP], reg, val);
}
static inline int cp_write_clr_set(struct v4l2_subdev *sd, u8 reg, u8 mask, u8 val)
@ -642,14 +629,14 @@ static inline int vdp_read(struct v4l2_subdev *sd, u8 reg)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_read_byte_data(state, ADV7604_PAGE_VDP, reg);
return adv76xx_read_check(state, ADV7604_PAGE_VDP, reg);
}
static inline int vdp_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
struct adv76xx_state *state = to_state(sd);
return adv_smbus_write_byte_data(state, ADV7604_PAGE_VDP, reg, val);
return regmap_write(state->regmap[ADV7604_PAGE_VDP], reg, val);
}
#define ADV76XX_REG(page, offset) (((page) << 8) | (offset))
@ -660,13 +647,16 @@ static int adv76xx_read_reg(struct v4l2_subdev *sd, unsigned int reg)
{
struct adv76xx_state *state = to_state(sd);
unsigned int page = reg >> 8;
unsigned int val;
int err;
if (!(BIT(page) & state->info->page_mask))
return -EINVAL;
reg &= 0xff;
err = regmap_read(state->regmap[page], reg, &val);
return adv_smbus_read_byte_data(state, page, reg);
return err ? err : val;
}
#endif
@ -680,7 +670,7 @@ static int adv76xx_write_reg(struct v4l2_subdev *sd, unsigned int reg, u8 val)
reg &= 0xff;
return adv_smbus_write_byte_data(state, page, reg, val);
return regmap_write(state->regmap[page], reg, val);
}
static void adv76xx_write_reg_seq(struct v4l2_subdev *sd,
@ -766,6 +756,23 @@ static const struct adv76xx_format_info adv7611_formats[] = {
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_12BIT },
};
static const struct adv76xx_format_info adv7612_formats[] = {
{ MEDIA_BUS_FMT_RGB888_1X24, ADV76XX_OP_CH_SEL_RGB, true, false,
ADV76XX_OP_MODE_SEL_SDR_444 | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YUYV8_2X8, ADV76XX_OP_CH_SEL_RGB, false, false,
ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YVYU8_2X8, ADV76XX_OP_CH_SEL_RGB, false, true,
ADV76XX_OP_MODE_SEL_SDR_422 | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_UYVY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, false,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_VYUY8_1X16, ADV76XX_OP_CH_SEL_RBG, false, true,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YUYV8_1X16, ADV76XX_OP_CH_SEL_RGB, false, false,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
{ MEDIA_BUS_FMT_YVYU8_1X16, ADV76XX_OP_CH_SEL_RGB, false, true,
ADV76XX_OP_MODE_SEL_SDR_422_2X | ADV76XX_OP_FORMAT_SEL_8BIT },
};
static const struct adv76xx_format_info *
adv76xx_format_info(struct adv76xx_state *state, u32 code)
{
@ -870,6 +877,16 @@ static unsigned int adv7611_read_cable_det(struct v4l2_subdev *sd)
return value & 1;
}
static unsigned int adv7612_read_cable_det(struct v4l2_subdev *sd)
{
/* Reads CABLE_DET_A_RAW. For input B support, need to
* account for bit 7 [MSB] of 0x6a (ie. CABLE_DET_B_RAW)
*/
u8 value = io_read(sd, 0x6f);
return value & 1;
}
static int adv76xx_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
{
struct adv76xx_state *state = to_state(sd);
@ -976,8 +993,8 @@ static void configure_custom_video_timings(struct v4l2_subdev *sd,
/* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
/* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
/* IO-map reg. 0x16 and 0x17 should be written in sequence */
if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_IO,
0x16, 2, pll))
if (regmap_raw_write(state->regmap[ADV76XX_PAGE_IO],
0x16, pll, 2))
v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
/* active video - horizontal timing */
@ -1028,8 +1045,8 @@ static void adv76xx_set_offset(struct v4l2_subdev *sd, bool auto_offset, u16 off
offset_buf[3] = offset_c & 0x0ff;
/* Registers must be written in this order with no i2c access in between */
if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_CP,
0x77, 4, offset_buf))
if (regmap_raw_write(state->regmap[ADV76XX_PAGE_CP],
0x77, offset_buf, 4))
v4l2_err(sd, "%s: i2c error writing to CP reg 0x77, 0x78, 0x79, 0x7a\n", __func__);
}
@ -1058,8 +1075,8 @@ static void adv76xx_set_gain(struct v4l2_subdev *sd, bool auto_gain, u16 gain_a,
gain_buf[3] = ((gain_c & 0x0ff));
/* Registers must be written in this order with no i2c access in between */
if (adv_smbus_write_i2c_block_data(state, ADV76XX_PAGE_CP,
0x73, 4, gain_buf))
if (regmap_raw_write(state->regmap[ADV76XX_PAGE_CP],
0x73, gain_buf, 4))
v4l2_err(sd, "%s: i2c error writing to CP reg 0x73, 0x74, 0x75, 0x76\n", __func__);
}
@ -1328,7 +1345,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
}
}
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
false, timings))
@ -1760,8 +1777,8 @@ static int adv76xx_s_routing(struct v4l2_subdev *sd,
select_input(sd);
enable_input(sd);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv76xx_ev_fmt);
v4l2_subdev_notify_event(sd, &adv76xx_ev_fmt);
return 0;
}
@ -1928,8 +1945,7 @@ static int adv76xx_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
"%s: fmt_change = 0x%x, fmt_change_digital = 0x%x\n",
__func__, fmt_change, fmt_change_digital);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv76xx_ev_fmt);
v4l2_subdev_notify_event(sd, &adv76xx_ev_fmt);
if (handled)
*handled = true;
@ -2347,6 +2363,20 @@ static int adv76xx_log_status(struct v4l2_subdev *sd)
return 0;
}
static int adv76xx_subscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
switch (sub->type) {
case V4L2_EVENT_SOURCE_CHANGE:
return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
case V4L2_EVENT_CTRL:
return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
default:
return -EINVAL;
}
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops adv76xx_ctrl_ops = {
@ -2356,6 +2386,8 @@ static const struct v4l2_ctrl_ops adv76xx_ctrl_ops = {
static const struct v4l2_subdev_core_ops adv76xx_core_ops = {
.log_status = adv76xx_log_status,
.interrupt_service_routine = adv76xx_isr,
.subscribe_event = adv76xx_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv76xx_g_register,
.s_register = adv76xx_s_register,
@ -2510,6 +2542,11 @@ static void adv7611_setup_irqs(struct v4l2_subdev *sd)
io_write(sd, 0x41, 0xd0); /* STDI irq for any change, disable INT2 */
}
static void adv7612_setup_irqs(struct v4l2_subdev *sd)
{
io_write(sd, 0x41, 0xd0); /* disable INT2 */
}
static void adv76xx_unregister_clients(struct adv76xx_state *state)
{
unsigned int i;
@ -2597,6 +2634,19 @@ static const struct adv76xx_reg_seq adv7611_recommended_settings_hdmi[] = {
{ ADV76XX_REG_SEQ_TERM, 0 },
};
static const struct adv76xx_reg_seq adv7612_recommended_settings_hdmi[] = {
{ ADV76XX_REG(ADV76XX_PAGE_CP, 0x6c), 0x00 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x9b), 0x03 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x6f), 0x08 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x85), 0x1f },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x87), 0x70 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x57), 0xda },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x58), 0x01 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x03), 0x98 },
{ ADV76XX_REG(ADV76XX_PAGE_HDMI, 0x4c), 0x44 },
{ ADV76XX_REG_SEQ_TERM, 0 },
};
static const struct adv76xx_chip_info adv76xx_chip_info[] = {
[ADV7604] = {
.type = ADV7604,
@ -2685,17 +2735,60 @@ static const struct adv76xx_chip_info adv76xx_chip_info[] = {
.field1_vsync_mask = 0x3fff,
.field1_vbackporch_mask = 0x3fff,
},
[ADV7612] = {
.type = ADV7612,
.has_afe = false,
.max_port = ADV76XX_PAD_HDMI_PORT_A, /* B not supported */
.num_dv_ports = 1, /* normally 2 */
.edid_enable_reg = 0x74,
.edid_status_reg = 0x76,
.lcf_reg = 0xa3,
.tdms_lock_mask = 0x43,
.cable_det_mask = 0x01,
.fmt_change_digital_mask = 0x03,
.cp_csc = 0xf4,
.formats = adv7612_formats,
.nformats = ARRAY_SIZE(adv7612_formats),
.set_termination = adv7611_set_termination,
.setup_irqs = adv7612_setup_irqs,
.read_hdmi_pixelclock = adv7611_read_hdmi_pixelclock,
.read_cable_det = adv7612_read_cable_det,
.recommended_settings = {
[1] = adv7612_recommended_settings_hdmi,
},
.num_recommended_settings = {
[1] = ARRAY_SIZE(adv7612_recommended_settings_hdmi),
},
.page_mask = BIT(ADV76XX_PAGE_IO) | BIT(ADV76XX_PAGE_CEC) |
BIT(ADV76XX_PAGE_INFOFRAME) | BIT(ADV76XX_PAGE_AFE) |
BIT(ADV76XX_PAGE_REP) | BIT(ADV76XX_PAGE_EDID) |
BIT(ADV76XX_PAGE_HDMI) | BIT(ADV76XX_PAGE_CP),
.linewidth_mask = 0x1fff,
.field0_height_mask = 0x1fff,
.field1_height_mask = 0x1fff,
.hfrontporch_mask = 0x1fff,
.hsync_mask = 0x1fff,
.hbackporch_mask = 0x1fff,
.field0_vfrontporch_mask = 0x3fff,
.field0_vsync_mask = 0x3fff,
.field0_vbackporch_mask = 0x3fff,
.field1_vfrontporch_mask = 0x3fff,
.field1_vsync_mask = 0x3fff,
.field1_vbackporch_mask = 0x3fff,
},
};
static const struct i2c_device_id adv76xx_i2c_id[] = {
{ "adv7604", (kernel_ulong_t)&adv76xx_chip_info[ADV7604] },
{ "adv7611", (kernel_ulong_t)&adv76xx_chip_info[ADV7611] },
{ "adv7612", (kernel_ulong_t)&adv76xx_chip_info[ADV7612] },
{ }
};
MODULE_DEVICE_TABLE(i2c, adv76xx_i2c_id);
static const struct of_device_id adv76xx_of_id[] __maybe_unused = {
{ .compatible = "adi,adv7611", .data = &adv76xx_chip_info[ADV7611] },
{ .compatible = "adi,adv7612", .data = &adv76xx_chip_info[ADV7612] },
{ }
};
MODULE_DEVICE_TABLE(of, adv76xx_of_id);
@ -2706,6 +2799,7 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
struct device_node *endpoint;
struct device_node *np;
unsigned int flags;
u32 v;
np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
@ -2715,6 +2809,12 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
return -EINVAL;
v4l2_of_parse_endpoint(endpoint, &bus_cfg);
if (!of_property_read_u32(endpoint, "default-input", &v))
state->pdata.default_input = v;
else
state->pdata.default_input = -1;
of_node_put(endpoint);
flags = bus_cfg.bus.parallel.flags;
@ -2753,7 +2853,6 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
/* Hardcode the remaining platform data fields. */
state->pdata.disable_pwrdnb = 0;
state->pdata.disable_cable_det_rst = 0;
state->pdata.default_input = -1;
state->pdata.blank_data = 1;
state->pdata.alt_data_sat = 1;
state->pdata.op_format_mode_sel = ADV7604_OP_FORMAT_MODE0;
@ -2762,6 +2861,148 @@ static int adv76xx_parse_dt(struct adv76xx_state *state)
return 0;
}
static const struct regmap_config adv76xx_regmap_cnf[] = {
{
.name = "io",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "avlink",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "cec",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "infoframe",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "esdp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "epp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "afe",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "rep",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "edid",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "hdmi",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "test",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "cp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
{
.name = "vdp",
.reg_bits = 8,
.val_bits = 8,
.max_register = 0xff,
.cache_type = REGCACHE_NONE,
},
};
static int configure_regmap(struct adv76xx_state *state, int region)
{
int err;
if (!state->i2c_clients[region])
return -ENODEV;
state->regmap[region] =
devm_regmap_init_i2c(state->i2c_clients[region],
&adv76xx_regmap_cnf[region]);
if (IS_ERR(state->regmap[region])) {
err = PTR_ERR(state->regmap[region]);
v4l_err(state->i2c_clients[region],
"Error initializing regmap %d with error %d\n",
region, err);
return -EINVAL;
}
return 0;
}
static int configure_regmaps(struct adv76xx_state *state)
{
int i, err;
for (i = ADV7604_PAGE_AVLINK ; i < ADV76XX_PAGE_MAX; i++) {
err = configure_regmap(state, i);
if (err && (err != -ENODEV))
return err;
}
return 0;
}
static int adv76xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@ -2771,7 +3012,7 @@ static int adv76xx_probe(struct i2c_client *client,
struct v4l2_ctrl_handler *hdl;
struct v4l2_subdev *sd;
unsigned int i;
u16 val;
unsigned int val, val2;
int err;
/* Check if the adapter supports the needed features */
@ -2833,28 +3074,59 @@ static int adv76xx_probe(struct i2c_client *client,
snprintf(sd->name, sizeof(sd->name), "%s %d-%04x",
id->name, i2c_adapter_id(client->adapter),
client->addr);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
/* Configure IO Regmap region */
err = configure_regmap(state, ADV76XX_PAGE_IO);
if (err) {
v4l2_err(sd, "Error configuring IO regmap region\n");
return -ENODEV;
}
/*
* Verify that the chip is present. On ADV7604 the RD_INFO register only
* identifies the revision, while on ADV7611 it identifies the model as
* well. Use the HDMI slave address on ADV7604 and RD_INFO on ADV7611.
*/
if (state->info->type == ADV7604) {
val = adv_smbus_read_byte_data_check(client, 0xfb, false);
switch (state->info->type) {
case ADV7604:
err = regmap_read(state->regmap[ADV76XX_PAGE_IO], 0xfb, &val);
if (err) {
v4l2_err(sd, "Error %d reading IO Regmap\n", err);
return -ENODEV;
}
if (val != 0x68) {
v4l2_info(sd, "not an adv7604 on address 0x%x\n",
v4l2_err(sd, "not an adv7604 on address 0x%x\n",
client->addr << 1);
return -ENODEV;
}
} else {
val = (adv_smbus_read_byte_data_check(client, 0xea, false) << 8)
| (adv_smbus_read_byte_data_check(client, 0xeb, false) << 0);
if (val != 0x2051) {
v4l2_info(sd, "not an adv7611 on address 0x%x\n",
break;
case ADV7611:
case ADV7612:
err = regmap_read(state->regmap[ADV76XX_PAGE_IO],
0xea,
&val);
if (err) {
v4l2_err(sd, "Error %d reading IO Regmap\n", err);
return -ENODEV;
}
val2 = val << 8;
err = regmap_read(state->regmap[ADV76XX_PAGE_IO],
0xeb,
&val);
if (err) {
v4l2_err(sd, "Error %d reading IO Regmap\n", err);
return -ENODEV;
}
val |= val2;
if ((state->info->type == ADV7611 && val != 0x2051) ||
(state->info->type == ADV7612 && val != 0x2041)) {
v4l2_err(sd, "not an adv761x on address 0x%x\n",
client->addr << 1);
return -ENODEV;
}
break;
}
/* control handlers */
@ -2941,6 +3213,11 @@ static int adv76xx_probe(struct i2c_client *client,
if (err)
goto err_work_queues;
/* Configure regmaps */
err = configure_regmaps(state);
if (err)
goto err_entity;
err = adv76xx_core_init(sd);
if (err)
goto err_entity;
@ -2985,7 +3262,6 @@ static int adv76xx_remove(struct i2c_client *client)
static struct i2c_driver adv76xx_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7604",
.of_match_table = of_match_ptr(adv76xx_of_id),
},

View file

@ -40,6 +40,7 @@
#include <linux/v4l2-dv-timings.h>
#include <linux/hdmi.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dv-timings.h>
#include <media/adv7842.h>
@ -1442,7 +1443,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
}
}
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs,
if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
false, timings))
@ -1980,8 +1981,7 @@ static int adv7842_s_routing(struct v4l2_subdev *sd,
select_input(sd, state->vid_std_select);
enable_input(sd);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv7842_ev_fmt);
v4l2_subdev_notify_event(sd, &adv7842_ev_fmt);
return 0;
}
@ -2214,8 +2214,7 @@ static int adv7842_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
"%s: fmt_change_cp = 0x%x, fmt_change_digital = 0x%x, fmt_change_sdp = 0x%x\n",
__func__, fmt_change_cp, fmt_change_digital,
fmt_change_sdp);
v4l2_subdev_notify(sd, V4L2_DEVICE_NOTIFY_EVENT,
(void *)&adv7842_ev_fmt);
v4l2_subdev_notify_event(sd, &adv7842_ev_fmt);
if (handled)
*handled = true;
}
@ -3005,6 +3004,20 @@ static long adv7842_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
return -ENOTTY;
}
static int adv7842_subscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
switch (sub->type) {
case V4L2_EVENT_SOURCE_CHANGE:
return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);
case V4L2_EVENT_CTRL:
return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);
default:
return -EINVAL;
}
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops adv7842_ctrl_ops = {
@ -3015,6 +3028,8 @@ static const struct v4l2_subdev_core_ops adv7842_core_ops = {
.log_status = adv7842_log_status,
.ioctl = adv7842_ioctl,
.interrupt_service_routine = adv7842_isr,
.subscribe_event = adv7842_subscribe_event,
.unsubscribe_event = v4l2_event_subdev_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = adv7842_g_register,
.s_register = adv7842_s_register,
@ -3210,7 +3225,7 @@ static int adv7842_probe(struct i2c_client *client,
sd = &state->sd;
v4l2_i2c_subdev_init(sd, client, &adv7842_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
state->mode = pdata->mode;
state->hdmi_port_a = pdata->input == ADV7842_SELECT_HDMI_PORT_A;
@ -3348,7 +3363,6 @@ MODULE_DEVICE_TABLE(i2c, adv7842_id);
static struct i2c_driver adv7842_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "adv7842",
},
.probe = adv7842_probe,

View file

@ -156,12 +156,12 @@ static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
} else if (std == V4L2_STD_PAL_60) {
vp1 = 7;
ak881x->lines = 480;
} else if (std && !(std & ~V4L2_STD_PAL)) {
vp1 = 0xf;
ak881x->lines = 576;
} else if (std && !(std & ~V4L2_STD_NTSC)) {
} else if (std & V4L2_STD_NTSC) {
vp1 = 0;
ak881x->lines = 480;
} else if (std & V4L2_STD_PAL) {
vp1 = 0xf;
ak881x->lines = 576;
} else {
/* No SECAM or PAL_N/Nc supported */
return -EINVAL;

View file

@ -379,16 +379,6 @@ static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
.s_ctrl = bt819_s_ctrl,
};
static const struct v4l2_subdev_core_ops bt819_core_ops = {
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops bt819_video_ops = {
.s_std = bt819_s_std,
.s_routing = bt819_s_routing,
@ -398,7 +388,6 @@ static const struct v4l2_subdev_video_ops bt819_video_ops = {
};
static const struct v4l2_subdev_ops bt819_ops = {
.core = &bt819_core_ops,
.video = &bt819_video_ops,
};
@ -492,7 +481,6 @@ MODULE_DEVICE_TABLE(i2c, bt819_id);
static struct i2c_driver bt819_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "bt819",
},
.probe = bt819_probe,

View file

@ -252,7 +252,6 @@ MODULE_DEVICE_TABLE(i2c, bt856_id);
static struct i2c_driver bt856_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "bt856",
},
.probe = bt856_probe,

View file

@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE(i2c, bt866_id);
static struct i2c_driver bt866_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "bt866",
},
.probe = bt866_probe,

View file

@ -132,13 +132,6 @@ static const struct v4l2_ctrl_ops cs5345_ctrl_ops = {
static const struct v4l2_subdev_core_ops cs5345_core_ops = {
.log_status = cs5345_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = cs5345_g_register,
.s_register = cs5345_s_register,
@ -218,7 +211,6 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id);
static struct i2c_driver cs5345_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cs5345",
},
.probe = cs5345_probe,

View file

@ -228,7 +228,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
static struct i2c_driver cs53l32a_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cs53l32a",
},
.probe = cs53l32a_probe,

View file

@ -5348,7 +5348,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id);
static struct i2c_driver cx25840_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "cx25840",
},
.probe = cx25840_probe,

View file

@ -478,6 +478,7 @@ static const struct i2c_device_id ir_kbd_id[] = {
{ "ir_rx_z8f0811_hdpvr", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
static struct i2c_driver ir_kbd_driver = {
.driver = {

View file

@ -708,7 +708,6 @@ MODULE_DEVICE_TABLE(i2c, ks0127_id);
static struct i2c_driver ks0127_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ks0127",
},
.probe = ks0127_probe,

View file

@ -185,7 +185,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
static struct i2c_driver m52790_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "m52790",
},
.probe = m52790_probe,

View file

@ -894,7 +894,6 @@ MODULE_DEVICE_TABLE(i2c, msp_id);
static struct i2c_driver msp_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "msp3400",
.pm = &msp3400_pm_ops,
},

View file

@ -583,7 +583,6 @@ MODULE_DEVICE_TABLE(i2c, mt9v011_id);
static struct i2c_driver mt9v011_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "mt9v011",
},
.probe = mt9v011_probe,

View file

@ -882,7 +882,7 @@ static const struct regmap_config mt9v032_regmap_config = {
static struct mt9v032_platform_data *
mt9v032_get_pdata(struct i2c_client *client)
{
struct mt9v032_platform_data *pdata;
struct mt9v032_platform_data *pdata = NULL;
struct v4l2_of_endpoint endpoint;
struct device_node *np;
struct property *prop;

View file

@ -909,7 +909,6 @@ static void ov2659_pll_calc_params(struct ov2659 *ov2659)
u8 ctrl1_reg = 0, ctrl2_reg = 0, ctrl3_reg = 0;
struct i2c_client *client = ov2659->client;
unsigned int desired = pdata->link_frequency;
u32 s_prediv = 1, s_postdiv = 1, s_mult = 1;
u32 prediv, postdiv, mult;
u32 bestdelta = -1;
u32 delta, actual;
@ -929,9 +928,6 @@ static void ov2659_pll_calc_params(struct ov2659 *ov2659)
if ((delta < bestdelta) || (bestdelta == -1)) {
bestdelta = delta;
s_mult = mult;
s_prediv = prediv;
s_postdiv = postdiv;
ctrl1_reg = ctrl1[i].reg;
ctrl2_reg = mult;
ctrl3_reg = ctrl3[j].reg;

View file

@ -94,7 +94,6 @@ MODULE_DEVICE_TABLE(i2c, ov7640_id);
static struct i2c_driver ov7640_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ov7640",
},
.probe = ov7640_probe,

View file

@ -1674,7 +1674,6 @@ MODULE_DEVICE_TABLE(i2c, ov7670_id);
static struct i2c_driver ov7670_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ov7670",
},
.probe = ov7670_probe,

View file

@ -1436,7 +1436,7 @@ static int ov965x_detect_sensor(struct v4l2_subdev *sd)
int ret;
mutex_lock(&ov965x->lock);
__ov965x_set_power(ov965x, 1);
__ov965x_set_power(ov965x, 1);
usleep_range(25000, 26000);
/* Check sensor revision */

View file

@ -149,7 +149,6 @@ int s5c73m3_register_spi_driver(struct s5c73m3 *state)
spidrv->remove = s5c73m3_spi_remove;
spidrv->probe = s5c73m3_spi_probe;
spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
spidrv->driver.bus = &spi_bus_type;
spidrv->driver.owner = THIS_MODULE;
spidrv->driver.of_match_table = s5c73m3_spi_ids;

View file

@ -363,6 +363,7 @@ static int s5k6a3_remove(struct i2c_client *client)
static const struct i2c_device_id s5k6a3_ids[] = {
{ }
};
MODULE_DEVICE_TABLE(i2c, s5k6a3_ids);
#ifdef CONFIG_OF
static const struct of_device_id s5k6a3_of_match[] = {

View file

@ -301,9 +301,7 @@ static void saa6588_i2c_poll(struct saa6588 *s)
first and the last of the 3 bytes block.
*/
tmp = tmpbuf[2];
tmpbuf[2] = tmpbuf[0];
tmpbuf[0] = tmp;
swap(tmpbuf[2], tmpbuf[0]);
/* Map 'Invalid block E' to 'Invalid Block' */
if (blocknum == 6)
@ -520,7 +518,6 @@ MODULE_DEVICE_TABLE(i2c, saa6588_id);
static struct i2c_driver saa6588_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa6588",
},
.probe = saa6588_probe,

View file

@ -793,7 +793,6 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
static struct i2c_driver saa6752hs_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa6752hs",
},
.probe = saa6752hs_probe,

View file

@ -357,16 +357,6 @@ static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
.s_ctrl = saa7110_s_ctrl,
};
static const struct v4l2_subdev_core_ops saa7110_core_ops = {
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops saa7110_video_ops = {
.s_std = saa7110_s_std,
.s_routing = saa7110_s_routing,
@ -376,7 +366,6 @@ static const struct v4l2_subdev_video_ops saa7110_video_ops = {
};
static const struct v4l2_subdev_ops saa7110_ops = {
.core = &saa7110_core_ops,
.video = &saa7110_video_ops,
};
@ -472,7 +461,6 @@ MODULE_DEVICE_TABLE(i2c, saa7110_id);
static struct i2c_driver saa7110_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7110",
},
.probe = saa7110_probe,

View file

@ -1929,7 +1929,6 @@ MODULE_DEVICE_TABLE(i2c, saa711x_id);
static struct i2c_driver saa711x_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7115",
},
.probe = saa711x_probe,

View file

@ -822,7 +822,6 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id);
static struct i2c_driver saa7127_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7127",
},
.probe = saa7127_probe,

View file

@ -1204,13 +1204,6 @@ static const struct v4l2_subdev_core_ops saa717x_core_ops = {
.g_register = saa717x_g_register,
.s_register = saa717x_s_register,
#endif
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
.log_status = saa717x_log_status,
};
@ -1363,7 +1356,6 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
static struct i2c_driver saa717x_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa717x",
},
.probe = saa717x_probe,

View file

@ -356,7 +356,6 @@ MODULE_DEVICE_TABLE(i2c, saa7185_id);
static struct i2c_driver saa7185_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7185",
},
.probe = saa7185_probe,

View file

@ -104,22 +104,22 @@ struct mt9t112_priv {
static const struct mt9t112_format mt9t112_cfmts[] = {
{
.code = MEDIA_BUS_FMT_UYVY8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 0,
}, {
.code = MEDIA_BUS_FMT_VYUY8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 1,
}, {
.code = MEDIA_BUS_FMT_YUYV8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 2,
}, {
.code = MEDIA_BUS_FMT_YVYU8_2X8,
.colorspace = V4L2_COLORSPACE_JPEG,
.colorspace = V4L2_COLORSPACE_SRGB,
.fmt = 1,
.order = 3,
}, {

View file

@ -510,13 +510,39 @@ static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct tw9910_priv *priv = to_tw9910(client);
const unsigned hact = 720;
const unsigned hdelay = 15;
unsigned vact;
unsigned vdelay;
int ret;
if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
return -EINVAL;
priv->norm = norm;
if (norm & V4L2_STD_525_60) {
vact = 240;
vdelay = 18;
ret = tw9910_mask_set(client, VVBI, 0x10, 0x10);
} else {
vact = 288;
vdelay = 24;
ret = tw9910_mask_set(client, VVBI, 0x10, 0x00);
}
if (!ret)
ret = i2c_smbus_write_byte_data(client, CROP_HI,
((vdelay >> 2) & 0xc0) |
((vact >> 4) & 0x30) |
((hdelay >> 6) & 0x0c) |
((hact >> 8) & 0x03));
if (!ret)
ret = i2c_smbus_write_byte_data(client, VDELAY_LO,
vdelay & 0xff);
if (!ret)
ret = i2c_smbus_write_byte_data(client, VACTIVE_LO,
vact & 0xff);
return 0;
return ret;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
@ -711,7 +737,7 @@ static int tw9910_get_fmt(struct v4l2_subdev *sd,
mf->width = priv->scale->width;
mf->height = priv->scale->height;
mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
mf->field = V4L2_FIELD_INTERLACED_BT;
return 0;
@ -732,7 +758,7 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
if (mf->code != MEDIA_BUS_FMT_UYVY8_2X8)
return -EINVAL;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
ret = tw9910_set_frame(sd, &width, &height);
if (!ret) {
@ -762,7 +788,7 @@ static int tw9910_set_fmt(struct v4l2_subdev *sd,
}
mf->code = MEDIA_BUS_FMT_UYVY8_2X8;
mf->colorspace = V4L2_COLORSPACE_JPEG;
mf->colorspace = V4L2_COLORSPACE_SMPTE170M;
/*
* select suitable norm
@ -820,6 +846,7 @@ static int tw9910_video_probe(struct i2c_client *client)
"tw9910 Product ID %0x:%0x\n", id, priv->revision);
priv->norm = V4L2_STD_NTSC;
priv->scale = &tw9910_ntsc_scales[0];
done:
tw9910_s_power(&priv->subdev, 0);

View file

@ -388,7 +388,6 @@ MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
static struct i2c_driver sony_btf_mpx_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "sony-btf-mpx",
},
.probe = sony_btf_mpx_probe,

View file

@ -489,18 +489,14 @@ static int sr030pc30_get_fmt(struct v4l2_subdev *sd,
{
struct v4l2_mbus_framefmt *mf;
struct sr030pc30_info *info = to_sr030pc30(sd);
int ret;
if (!format || format->pad)
return -EINVAL;
mf = &format->format;
if (!info->curr_win || !info->curr_fmt) {
ret = sr030pc30_set_params(sd);
if (ret)
return ret;
}
if (!info->curr_win || !info->curr_fmt)
return -EINVAL;
mf->width = info->curr_win->width;
mf->height = info->curr_win->height;
@ -636,13 +632,6 @@ static const struct v4l2_ctrl_ops sr030pc30_ctrl_ops = {
static const struct v4l2_subdev_core_ops sr030pc30_core_ops = {
.s_power = sr030pc30_s_power,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_pad_ops sr030pc30_pad_ops = {

1979
drivers/media/i2c/tc358743.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,681 @@
/*
* tc358743 - Toshiba HDMI to CSI-2 bridge - register names and bit masks
*
* Copyright 2015 Cisco Systems, Inc. and/or its affiliates. All rights
* reserved.
*
* This program is free software; you may redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
/*
* References (c = chapter, p = page):
* REF_01 - Toshiba, TC358743XBG (H2C), Functional Specification, Rev 0.60
*/
/* Bit masks has prefix 'MASK_' and options after '_'. */
#ifndef __TC358743_REGS_H
#define __TC358743_REGS_H
#define CHIPID 0x0000
#define MASK_CHIPID 0xff00
#define MASK_REVID 0x00ff
#define SYSCTL 0x0002
#define MASK_IRRST 0x0800
#define MASK_CECRST 0x0400
#define MASK_CTXRST 0x0200
#define MASK_HDMIRST 0x0100
#define MASK_SLEEP 0x0001
#define CONFCTL 0x0004
#define MASK_PWRISO 0x8000
#define MASK_ACLKOPT 0x1000
#define MASK_AUDCHNUM 0x0c00
#define MASK_AUDCHNUM_8 0x0000
#define MASK_AUDCHNUM_6 0x0400
#define MASK_AUDCHNUM_4 0x0800
#define MASK_AUDCHNUM_2 0x0c00
#define MASK_AUDCHSEL 0x0200
#define MASK_I2SDLYOPT 0x0100
#define MASK_YCBCRFMT 0x00c0
#define MASK_YCBCRFMT_444 0x0000
#define MASK_YCBCRFMT_422_12_BIT 0x0040
#define MASK_YCBCRFMT_COLORBAR 0x0080
#define MASK_YCBCRFMT_422_8_BIT 0x00c0
#define MASK_INFRMEN 0x0020
#define MASK_AUDOUTSEL 0x0018
#define MASK_AUDOUTSEL_CSI 0x0000
#define MASK_AUDOUTSEL_I2S 0x0010
#define MASK_AUDOUTSEL_TDM 0x0018
#define MASK_AUTOINDEX 0x0004
#define MASK_ABUFEN 0x0002
#define MASK_VBUFEN 0x0001
#define FIFOCTL 0x0006
#define INTSTATUS 0x0014
#define MASK_AMUTE_INT 0x0400
#define MASK_HDMI_INT 0x0200
#define MASK_CSI_INT 0x0100
#define MASK_SYS_INT 0x0020
#define MASK_CEC_EINT 0x0010
#define MASK_CEC_TINT 0x0008
#define MASK_CEC_RINT 0x0004
#define MASK_IR_EINT 0x0002
#define MASK_IR_DINT 0x0001
#define INTMASK 0x0016
#define MASK_AMUTE_MSK 0x0400
#define MASK_HDMI_MSK 0x0200
#define MASK_CSI_MSK 0x0100
#define MASK_SYS_MSK 0x0020
#define MASK_CEC_EMSK 0x0010
#define MASK_CEC_TMSK 0x0008
#define MASK_CEC_RMSK 0x0004
#define MASK_IR_EMSK 0x0002
#define MASK_IR_DMSK 0x0001
#define INTFLAG 0x0018
#define INTSYSSTATUS 0x001A
#define PLLCTL0 0x0020
#define MASK_PLL_PRD 0xf000
#define SET_PLL_PRD(prd) ((((prd) - 1) << 12) &\
MASK_PLL_PRD)
#define MASK_PLL_FBD 0x01ff
#define SET_PLL_FBD(fbd) (((fbd) - 1) & MASK_PLL_FBD)
#define PLLCTL1 0x0022
#define MASK_PLL_FRS 0x0c00
#define SET_PLL_FRS(frs) (((frs) << 10) & MASK_PLL_FRS)
#define MASK_PLL_LBWS 0x0300
#define MASK_LFBREN 0x0040
#define MASK_BYPCKEN 0x0020
#define MASK_CKEN 0x0010
#define MASK_RESETB 0x0002
#define MASK_PLL_EN 0x0001
#define CLW_CNTRL 0x0140
#define MASK_CLW_LANEDISABLE 0x0001
#define D0W_CNTRL 0x0144
#define MASK_D0W_LANEDISABLE 0x0001
#define D1W_CNTRL 0x0148
#define MASK_D1W_LANEDISABLE 0x0001
#define D2W_CNTRL 0x014C
#define MASK_D2W_LANEDISABLE 0x0001
#define D3W_CNTRL 0x0150
#define MASK_D3W_LANEDISABLE 0x0001
#define STARTCNTRL 0x0204
#define MASK_START 0x00000001
#define LINEINITCNT 0x0210
#define LPTXTIMECNT 0x0214
#define TCLK_HEADERCNT 0x0218
#define TCLK_TRAILCNT 0x021C
#define THS_HEADERCNT 0x0220
#define TWAKEUP 0x0224
#define TCLK_POSTCNT 0x0228
#define THS_TRAILCNT 0x022C
#define HSTXVREGCNT 0x0230
#define HSTXVREGEN 0x0234
#define MASK_D3M_HSTXVREGEN 0x0010
#define MASK_D2M_HSTXVREGEN 0x0008
#define MASK_D1M_HSTXVREGEN 0x0004
#define MASK_D0M_HSTXVREGEN 0x0002
#define MASK_CLM_HSTXVREGEN 0x0001
#define TXOPTIONCNTRL 0x0238
#define MASK_CONTCLKMODE 0x00000001
#define CSI_CONTROL 0x040C
#define MASK_CSI_MODE 0x8000
#define MASK_HTXTOEN 0x0400
#define MASK_TXHSMD 0x0080
#define MASK_HSCKMD 0x0020
#define MASK_NOL 0x0006
#define MASK_NOL_1 0x0000
#define MASK_NOL_2 0x0002
#define MASK_NOL_3 0x0004
#define MASK_NOL_4 0x0006
#define MASK_EOTDIS 0x0001
#define CSI_INT 0x0414
#define MASK_INTHLT 0x00000008
#define MASK_INTER 0x00000004
#define CSI_INT_ENA 0x0418
#define MASK_IENHLT 0x00000008
#define MASK_IENER 0x00000004
#define CSI_ERR 0x044C
#define MASK_INER 0x00000200
#define MASK_WCER 0x00000100
#define MASK_QUNK 0x00000010
#define MASK_TXBRK 0x00000002
#define CSI_ERR_INTENA 0x0450
#define CSI_ERR_HALT 0x0454
#define CSI_CONFW 0x0500
#define MASK_MODE 0xe0000000
#define MASK_MODE_SET 0xa0000000
#define MASK_MODE_CLEAR 0xc0000000
#define MASK_ADDRESS 0x1f000000
#define MASK_ADDRESS_CSI_CONTROL 0x03000000
#define MASK_ADDRESS_CSI_INT_ENA 0x06000000
#define MASK_ADDRESS_CSI_ERR_INTENA 0x14000000
#define MASK_ADDRESS_CSI_ERR_HALT 0x15000000
#define MASK_DATA 0x0000ffff
#define CSI_INT_CLR 0x050C
#define MASK_ICRER 0x00000004
#define CSI_START 0x0518
#define MASK_STRT 0x00000001
#define CECEN 0x0600
#define MASK_CECEN 0x0001
#define HDMI_INT0 0x8500
#define MASK_I_KEY 0x80
#define MASK_I_MISC 0x02
#define MASK_I_PHYERR 0x01
#define HDMI_INT1 0x8501
#define MASK_I_GBD 0x80
#define MASK_I_HDCP 0x40
#define MASK_I_ERR 0x20
#define MASK_I_AUD 0x10
#define MASK_I_CBIT 0x08
#define MASK_I_PACKET 0x04
#define MASK_I_CLK 0x02
#define MASK_I_SYS 0x01
#define SYS_INT 0x8502
#define MASK_I_ACR_CTS 0x80
#define MASK_I_ACRN 0x40
#define MASK_I_DVI 0x20
#define MASK_I_HDMI 0x10
#define MASK_I_NOPMBDET 0x08
#define MASK_I_DPMBDET 0x04
#define MASK_I_TMDS 0x02
#define MASK_I_DDC 0x01
#define CLK_INT 0x8503
#define MASK_I_OUT_H_CHG 0x40
#define MASK_I_IN_DE_CHG 0x20
#define MASK_I_IN_HV_CHG 0x10
#define MASK_I_DC_CHG 0x08
#define MASK_I_PXCLK_CHG 0x04
#define MASK_I_PHYCLK_CHG 0x02
#define MASK_I_TMDSCLK_CHG 0x01
#define CBIT_INT 0x8505
#define MASK_I_AF_LOCK 0x80
#define MASK_I_AF_UNLOCK 0x40
#define MASK_I_CBIT_FS 0x02
#define AUDIO_INT 0x8506
#define ERR_INT 0x8507
#define MASK_I_EESS_ERR 0x80
#define HDCP_INT 0x8508
#define MASK_I_AVM_SET 0x80
#define MASK_I_AVM_CLR 0x40
#define MASK_I_LINKERR 0x20
#define MASK_I_SHA_END 0x10
#define MASK_I_R0_END 0x08
#define MASK_I_KM_END 0x04
#define MASK_I_AKSV_END 0x02
#define MASK_I_AN_END 0x01
#define MISC_INT 0x850B
#define MASK_I_AS_LAYOUT 0x10
#define MASK_I_NO_SPD 0x08
#define MASK_I_NO_VS 0x03
#define MASK_I_SYNC_CHG 0x02
#define MASK_I_AUDIO_MUTE 0x01
#define KEY_INT 0x850F
#define SYS_INTM 0x8512
#define MASK_M_ACR_CTS 0x80
#define MASK_M_ACR_N 0x40
#define MASK_M_DVI_DET 0x20
#define MASK_M_HDMI_DET 0x10
#define MASK_M_NOPMBDET 0x08
#define MASK_M_BPMBDET 0x04
#define MASK_M_TMDS 0x02
#define MASK_M_DDC 0x01
#define CLK_INTM 0x8513
#define MASK_M_OUT_H_CHG 0x40
#define MASK_M_IN_DE_CHG 0x20
#define MASK_M_IN_HV_CHG 0x10
#define MASK_M_DC_CHG 0x08
#define MASK_M_PXCLK_CHG 0x04
#define MASK_M_PHYCLK_CHG 0x02
#define MASK_M_TMDS_CHG 0x01
#define PACKET_INTM 0x8514
#define CBIT_INTM 0x8515
#define MASK_M_AF_LOCK 0x80
#define MASK_M_AF_UNLOCK 0x40
#define MASK_M_CBIT_FS 0x02
#define AUDIO_INTM 0x8516
#define MASK_M_BUFINIT_END 0x01
#define ERR_INTM 0x8517
#define MASK_M_EESS_ERR 0x80
#define HDCP_INTM 0x8518
#define MASK_M_AVM_SET 0x80
#define MASK_M_AVM_CLR 0x40
#define MASK_M_LINKERR 0x20
#define MASK_M_SHA_END 0x10
#define MASK_M_R0_END 0x08
#define MASK_M_KM_END 0x04
#define MASK_M_AKSV_END 0x02
#define MASK_M_AN_END 0x01
#define MISC_INTM 0x851B
#define MASK_M_AS_LAYOUT 0x10
#define MASK_M_NO_SPD 0x08
#define MASK_M_NO_VS 0x03
#define MASK_M_SYNC_CHG 0x02
#define MASK_M_AUDIO_MUTE 0x01
#define KEY_INTM 0x851F
#define SYS_STATUS 0x8520
#define MASK_S_SYNC 0x80
#define MASK_S_AVMUTE 0x40
#define MASK_S_HDCP 0x20
#define MASK_S_HDMI 0x10
#define MASK_S_PHY_SCDT 0x08
#define MASK_S_PHY_PLL 0x04
#define MASK_S_TMDS 0x02
#define MASK_S_DDC5V 0x01
#define CSI_STATUS 0x0410
#define MASK_S_WSYNC 0x0400
#define MASK_S_TXACT 0x0200
#define MASK_S_RXACT 0x0100
#define MASK_S_HLT 0x0001
#define VI_STATUS1 0x8522
#define MASK_S_V_GBD 0x08
#define MASK_S_DEEPCOLOR 0x0c
#define MASK_S_V_422 0x02
#define MASK_S_V_INTERLACE 0x01
#define AU_STATUS0 0x8523
#define MASK_S_A_SAMPLE 0x01
#define VI_STATUS3 0x8528
#define MASK_S_V_COLOR 0x1e
#define MASK_LIMITED 0x01
#define PHY_CTL0 0x8531
#define MASK_PHY_SYSCLK_IND 0x02
#define MASK_PHY_CTL 0x01
#define PHY_CTL1 0x8532 /* Not in REF_01 */
#define MASK_PHY_AUTO_RST1 0xf0
#define MASK_PHY_AUTO_RST1_OFF 0x00
#define SET_PHY_AUTO_RST1_US(us) ((((us) / 200) << 4) & \
MASK_PHY_AUTO_RST1)
#define MASK_FREQ_RANGE_MODE 0x0f
#define SET_FREQ_RANGE_MODE_CYCLES(cycles) (((cycles) - 1) & \
MASK_FREQ_RANGE_MODE)
#define PHY_CTL2 0x8533 /* Not in REF_01 */
#define MASK_PHY_AUTO_RST4 0x04
#define MASK_PHY_AUTO_RST3 0x02
#define MASK_PHY_AUTO_RST2 0x01
#define MASK_PHY_AUTO_RSTn (MASK_PHY_AUTO_RST4 | \
MASK_PHY_AUTO_RST3 | \
MASK_PHY_AUTO_RST2)
#define PHY_EN 0x8534
#define MASK_ENABLE_PHY 0x01
#define PHY_RST 0x8535
#define MASK_RESET_CTRL 0x01 /* Reset active low */
#define PHY_BIAS 0x8536 /* Not in REF_01 */
#define PHY_CSQ 0x853F /* Not in REF_01 */
#define MASK_CSQ_CNT 0x0f
#define SET_CSQ_CNT_LEVEL(n) (n & MASK_CSQ_CNT)
#define SYS_FREQ0 0x8540
#define SYS_FREQ1 0x8541
#define SYS_CLK 0x8542 /* Not in REF_01 */
#define MASK_CLK_DIFF 0x0C
#define MASK_CLK_DIV 0x03
#define DDC_CTL 0x8543
#define MASK_DDC_ACK_POL 0x08
#define MASK_DDC_ACTION 0x04
#define MASK_DDC5V_MODE 0x03
#define MASK_DDC5V_MODE_0MS 0x00
#define MASK_DDC5V_MODE_50MS 0x01
#define MASK_DDC5V_MODE_100MS 0x02
#define MASK_DDC5V_MODE_200MS 0x03
#define HPD_CTL 0x8544
#define MASK_HPD_CTL0 0x10
#define MASK_HPD_OUT0 0x01
#define ANA_CTL 0x8545
#define MASK_APPL_PCSX 0x30
#define MASK_APPL_PCSX_HIZ 0x00
#define MASK_APPL_PCSX_L_FIX 0x10
#define MASK_APPL_PCSX_H_FIX 0x20
#define MASK_APPL_PCSX_NORMAL 0x30
#define MASK_ANALOG_ON 0x01
#define AVM_CTL 0x8546
#define INIT_END 0x854A
#define MASK_INIT_END 0x01
#define HDMI_DET 0x8552 /* Not in REF_01 */
#define MASK_HDMI_DET_MOD1 0x80
#define MASK_HDMI_DET_MOD0 0x40
#define MASK_HDMI_DET_V 0x30
#define MASK_HDMI_DET_V_SYNC 0x00
#define MASK_HDMI_DET_V_ASYNC_25MS 0x10
#define MASK_HDMI_DET_V_ASYNC_50MS 0x20
#define MASK_HDMI_DET_V_ASYNC_100MS 0x30
#define MASK_HDMI_DET_NUM 0x0f
#define HDCP_MODE 0x8560
#define MASK_MODE_RST_TN 0x20
#define MASK_LINE_REKEY 0x10
#define MASK_AUTO_CLR 0x04
#define HDCP_REG1 0x8563 /* Not in REF_01 */
#define MASK_AUTH_UNAUTH_SEL 0x70
#define MASK_AUTH_UNAUTH_SEL_12_FRAMES 0x70
#define MASK_AUTH_UNAUTH_SEL_8_FRAMES 0x60
#define MASK_AUTH_UNAUTH_SEL_4_FRAMES 0x50
#define MASK_AUTH_UNAUTH_SEL_2_FRAMES 0x40
#define MASK_AUTH_UNAUTH_SEL_64_FRAMES 0x30
#define MASK_AUTH_UNAUTH_SEL_32_FRAMES 0x20
#define MASK_AUTH_UNAUTH_SEL_16_FRAMES 0x10
#define MASK_AUTH_UNAUTH_SEL_ONCE 0x00
#define MASK_AUTH_UNAUTH 0x01
#define MASK_AUTH_UNAUTH_AUTO 0x01
#define HDCP_REG2 0x8564 /* Not in REF_01 */
#define MASK_AUTO_P3_RESET 0x0F
#define SET_AUTO_P3_RESET_FRAMES(n) (n & MASK_AUTO_P3_RESET)
#define MASK_AUTO_P3_RESET_OFF 0x00
#define VI_MODE 0x8570
#define MASK_RGB_DVI 0x08 /* Not in REF_01 */
#define VOUT_SET2 0x8573
#define MASK_SEL422 0x80
#define MASK_VOUT_422FIL_100 0x40
#define MASK_VOUTCOLORMODE 0x03
#define MASK_VOUTCOLORMODE_THROUGH 0x00
#define MASK_VOUTCOLORMODE_AUTO 0x01
#define MASK_VOUTCOLORMODE_MANUAL 0x03
#define VOUT_SET3 0x8574
#define MASK_VOUT_EXTCNT 0x08
#define VI_REP 0x8576
#define MASK_VOUT_COLOR_SEL 0xe0
#define MASK_VOUT_COLOR_RGB_FULL 0x00
#define MASK_VOUT_COLOR_RGB_LIMITED 0x20
#define MASK_VOUT_COLOR_601_YCBCR_FULL 0x40
#define MASK_VOUT_COLOR_601_YCBCR_LIMITED 0x60
#define MASK_VOUT_COLOR_709_YCBCR_FULL 0x80
#define MASK_VOUT_COLOR_709_YCBCR_LIMITED 0xa0
#define MASK_VOUT_COLOR_FULL_TO_LIMITED 0xc0
#define MASK_VOUT_COLOR_LIMITED_TO_FULL 0xe0
#define MASK_IN_REP_HEN 0x10
#define MASK_IN_REP 0x0f
#define VI_MUTE 0x857F
#define MASK_AUTO_MUTE 0xc0
#define MASK_VI_MUTE 0x10
#define DE_WIDTH_H_LO 0x8582 /* Not in REF_01 */
#define DE_WIDTH_H_HI 0x8583 /* Not in REF_01 */
#define DE_WIDTH_V_LO 0x8588 /* Not in REF_01 */
#define DE_WIDTH_V_HI 0x8589 /* Not in REF_01 */
#define H_SIZE_LO 0x858A /* Not in REF_01 */
#define H_SIZE_HI 0x858B /* Not in REF_01 */
#define V_SIZE_LO 0x858C /* Not in REF_01 */
#define V_SIZE_HI 0x858D /* Not in REF_01 */
#define FV_CNT_LO 0x85A1 /* Not in REF_01 */
#define FV_CNT_HI 0x85A2 /* Not in REF_01 */
#define FH_MIN0 0x85AA /* Not in REF_01 */
#define FH_MIN1 0x85AB /* Not in REF_01 */
#define FH_MAX0 0x85AC /* Not in REF_01 */
#define FH_MAX1 0x85AD /* Not in REF_01 */
#define HV_RST 0x85AF /* Not in REF_01 */
#define MASK_H_PI_RST 0x20
#define MASK_V_PI_RST 0x10
#define EDID_MODE 0x85C7
#define MASK_EDID_SPEED 0x40
#define MASK_EDID_MODE 0x03
#define MASK_EDID_MODE_DISABLE 0x00
#define MASK_EDID_MODE_DDC2B 0x01
#define MASK_EDID_MODE_E_DDC 0x02
#define EDID_LEN1 0x85CA
#define EDID_LEN2 0x85CB
#define HDCP_REG3 0x85D1 /* Not in REF_01 */
#define KEY_RD_CMD 0x01
#define FORCE_MUTE 0x8600
#define MASK_FORCE_AMUTE 0x10
#define MASK_FORCE_DMUTE 0x01
#define CMD_AUD 0x8601
#define MASK_CMD_BUFINIT 0x04
#define MASK_CMD_LOCKDET 0x02
#define MASK_CMD_MUTE 0x01
#define AUTO_CMD0 0x8602
#define MASK_AUTO_MUTE7 0x80
#define MASK_AUTO_MUTE6 0x40
#define MASK_AUTO_MUTE5 0x20
#define MASK_AUTO_MUTE4 0x10
#define MASK_AUTO_MUTE3 0x08
#define MASK_AUTO_MUTE2 0x04
#define MASK_AUTO_MUTE1 0x02
#define MASK_AUTO_MUTE0 0x01
#define AUTO_CMD1 0x8603
#define MASK_AUTO_MUTE10 0x04
#define MASK_AUTO_MUTE9 0x02
#define MASK_AUTO_MUTE8 0x01
#define AUTO_CMD2 0x8604
#define MASK_AUTO_PLAY3 0x08
#define MASK_AUTO_PLAY2 0x04
#define BUFINIT_START 0x8606
#define SET_BUFINIT_START_MS(milliseconds) ((milliseconds) / 100)
#define FS_MUTE 0x8607
#define MASK_FS_ELSE_MUTE 0x80
#define MASK_FS22_MUTE 0x40
#define MASK_FS24_MUTE 0x20
#define MASK_FS88_MUTE 0x10
#define MASK_FS96_MUTE 0x08
#define MASK_FS176_MUTE 0x04
#define MASK_FS192_MUTE 0x02
#define MASK_FS_NO_MUTE 0x01
#define FS_IMODE 0x8620
#define MASK_NLPCM_HMODE 0x40
#define MASK_NLPCM_SMODE 0x20
#define MASK_NLPCM_IMODE 0x10
#define MASK_FS_HMODE 0x08
#define MASK_FS_AMODE 0x04
#define MASK_FS_SMODE 0x02
#define MASK_FS_IMODE 0x01
#define FS_SET 0x8621
#define MASK_FS 0x0f
#define LOCKDET_REF0 0x8630
#define LOCKDET_REF1 0x8631
#define LOCKDET_REF2 0x8632
#define ACR_MODE 0x8640
#define MASK_ACR_LOAD 0x10
#define MASK_N_MODE 0x04
#define MASK_CTS_MODE 0x01
#define ACR_MDF0 0x8641
#define MASK_ACR_L2MDF 0x70
#define MASK_ACR_L2MDF_0_PPM 0x00
#define MASK_ACR_L2MDF_61_PPM 0x10
#define MASK_ACR_L2MDF_122_PPM 0x20
#define MASK_ACR_L2MDF_244_PPM 0x30
#define MASK_ACR_L2MDF_488_PPM 0x40
#define MASK_ACR_L2MDF_976_PPM 0x50
#define MASK_ACR_L2MDF_1976_PPM 0x60
#define MASK_ACR_L2MDF_3906_PPM 0x70
#define MASK_ACR_L1MDF 0x07
#define MASK_ACR_L1MDF_0_PPM 0x00
#define MASK_ACR_L1MDF_61_PPM 0x01
#define MASK_ACR_L1MDF_122_PPM 0x02
#define MASK_ACR_L1MDF_244_PPM 0x03
#define MASK_ACR_L1MDF_488_PPM 0x04
#define MASK_ACR_L1MDF_976_PPM 0x05
#define MASK_ACR_L1MDF_1976_PPM 0x06
#define MASK_ACR_L1MDF_3906_PPM 0x07
#define ACR_MDF1 0x8642
#define MASK_ACR_L3MDF 0x07
#define MASK_ACR_L3MDF_0_PPM 0x00
#define MASK_ACR_L3MDF_61_PPM 0x01
#define MASK_ACR_L3MDF_122_PPM 0x02
#define MASK_ACR_L3MDF_244_PPM 0x03
#define MASK_ACR_L3MDF_488_PPM 0x04
#define MASK_ACR_L3MDF_976_PPM 0x05
#define MASK_ACR_L3MDF_1976_PPM 0x06
#define MASK_ACR_L3MDF_3906_PPM 0x07
#define SDO_MODE1 0x8652
#define MASK_SDO_BIT_LENG 0x70
#define MASK_SDO_FMT 0x03
#define MASK_SDO_FMT_RIGHT 0x00
#define MASK_SDO_FMT_LEFT 0x01
#define MASK_SDO_FMT_I2S 0x02
#define DIV_MODE 0x8665 /* Not in REF_01 */
#define MASK_DIV_DLY 0xf0
#define SET_DIV_DLY_MS(milliseconds) ((((milliseconds) / 100) << 4) & \
MASK_DIV_DLY)
#define MASK_DIV_MODE 0x01
#define NCO_F0_MOD 0x8670
#define MASK_NCO_F0_MOD 0x03
#define MASK_NCO_F0_MOD_42MHZ 0x00
#define MASK_NCO_F0_MOD_27MHZ 0x01
#define PK_INT_MODE 0x8709
#define MASK_ISRC2_INT_MODE 0x80
#define MASK_ISRC_INT_MODE 0x40
#define MASK_ACP_INT_MODE 0x20
#define MASK_VS_INT_MODE 0x10
#define MASK_SPD_INT_MODE 0x08
#define MASK_MS_INT_MODE 0x04
#define MASK_AUD_INT_MODE 0x02
#define MASK_AVI_INT_MODE 0x01
#define NO_PKT_LIMIT 0x870B
#define MASK_NO_ACP_LIMIT 0xf0
#define SET_NO_ACP_LIMIT_MS(milliseconds) ((((milliseconds) / 80) << 4) & \
MASK_NO_ACP_LIMIT)
#define MASK_NO_AVI_LIMIT 0x0f
#define SET_NO_AVI_LIMIT_MS(milliseconds) (((milliseconds) / 80) & \
MASK_NO_AVI_LIMIT)
#define NO_PKT_CLR 0x870C
#define MASK_NO_VS_CLR 0x40
#define MASK_NO_SPD_CLR 0x20
#define MASK_NO_ACP_CLR 0x10
#define MASK_NO_AVI_CLR1 0x02
#define MASK_NO_AVI_CLR0 0x01
#define ERR_PK_LIMIT 0x870D
#define NO_PKT_LIMIT2 0x870E
#define PK_AVI_0HEAD 0x8710
#define PK_AVI_1HEAD 0x8711
#define PK_AVI_2HEAD 0x8712
#define PK_AVI_0BYTE 0x8713
#define PK_AVI_1BYTE 0x8714
#define PK_AVI_2BYTE 0x8715
#define PK_AVI_3BYTE 0x8716
#define PK_AVI_4BYTE 0x8717
#define PK_AVI_5BYTE 0x8718
#define PK_AVI_6BYTE 0x8719
#define PK_AVI_7BYTE 0x871A
#define PK_AVI_8BYTE 0x871B
#define PK_AVI_9BYTE 0x871C
#define PK_AVI_10BYTE 0x871D
#define PK_AVI_11BYTE 0x871E
#define PK_AVI_12BYTE 0x871F
#define PK_AVI_13BYTE 0x8720
#define PK_AVI_14BYTE 0x8721
#define PK_AVI_15BYTE 0x8722
#define PK_AVI_16BYTE 0x8723
#define BKSV 0x8800
#define BCAPS 0x8840
#define MASK_HDMI_RSVD 0x80
#define MASK_REPEATER 0x40
#define MASK_READY 0x20
#define MASK_FASTI2C 0x10
#define MASK_1_1_FEA 0x02
#define MASK_FAST_REAU 0x01
#define BSTATUS1 0x8842
#define MASK_MAX_EXCED 0x08
#define EDID_RAM 0x8C00
#define NO_GDB_LIMIT 0x9007
#endif

View file

@ -331,13 +331,6 @@ static const struct v4l2_ctrl_ops tda7432_ctrl_ops = {
static const struct v4l2_subdev_core_ops tda7432_core_ops = {
.log_status = tda7432_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_ops tda7432_ops = {
@ -416,7 +409,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
static struct i2c_driver tda7432_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tda7432",
},
.probe = tda7432_probe,

View file

@ -199,7 +199,6 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id);
static struct i2c_driver tda9840_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tda9840",
},
.probe = tda9840_probe,

View file

@ -162,7 +162,6 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id);
static struct i2c_driver tea6415c_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tea6415c",
},
.probe = tea6415c_probe,

View file

@ -144,7 +144,6 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
static struct i2c_driver tea6420_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tea6420",
},
.probe = tea6420_probe,

View file

@ -377,7 +377,6 @@ MODULE_DEVICE_TABLE(i2c, ths7303_id);
static struct i2c_driver ths7303_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "ths73x3",
},
.probe = ths7303_probe,

View file

@ -122,13 +122,6 @@ static const struct v4l2_ctrl_ops tlv320aic23b_ctrl_ops = {
static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
.log_status = tlv320aic23b_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {

View file

@ -2051,7 +2051,6 @@ MODULE_DEVICE_TABLE(i2c, tvaudio_id);
static struct i2c_driver tvaudio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tvaudio",
},
.probe = tvaudio_probe,

View file

@ -957,16 +957,6 @@ static int tvp514x_set_pad_format(struct v4l2_subdev *sd,
return 0;
}
static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
.s_std = tvp514x_s_std,
.s_routing = tvp514x_s_routing,
@ -983,7 +973,6 @@ static const struct v4l2_subdev_pad_ops tvp514x_pad_ops = {
};
static const struct v4l2_subdev_ops tvp514x_ops = {
.core = &tvp514x_core_ops,
.video = &tvp514x_video_ops,
.pad = &tvp514x_pad_ops,
};

View file

@ -1215,7 +1215,6 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id);
static struct i2c_driver tvp5150_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tvp5150",
},
.probe = tvp5150_probe,

View file

@ -861,13 +861,6 @@ tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cf
/* V4L2 core operation handlers */
static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
.log_status = tvp7002_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.g_register = tvp7002_g_register,
.s_register = tvp7002_s_register,

View file

@ -266,7 +266,6 @@ MODULE_DEVICE_TABLE(i2c, tw9903_id);
static struct i2c_driver tw9903_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tw9903",
},
.probe = tw9903_probe,

View file

@ -234,7 +234,6 @@ MODULE_DEVICE_TABLE(i2c, tw9906_id);
static struct i2c_driver tw9906_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tw9906",
},
.probe = tw9906_probe,

View file

@ -241,7 +241,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id);
static struct i2c_driver upd64031a_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "upd64031a",
},
.probe = upd64031a_probe,

View file

@ -213,7 +213,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id);
static struct i2c_driver upd64083_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "upd64083",
},
.probe = upd64083_probe,

View file

@ -194,7 +194,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
static struct i2c_driver vp27smpx_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "vp27smpx",
},
.probe = vp27smpx_probe,

View file

@ -450,13 +450,6 @@ static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
.init = vpx3220_init,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
@ -567,7 +560,6 @@ MODULE_DEVICE_TABLE(i2c, vpx3220_id);
static struct i2c_driver vpx3220_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "vpx3220",
},
.probe = vpx3220_probe,

View file

@ -176,13 +176,6 @@ static const struct v4l2_ctrl_ops wm8739_ctrl_ops = {
static const struct v4l2_subdev_core_ops wm8739_core_ops = {
.log_status = wm8739_log_status,
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
.g_ctrl = v4l2_subdev_g_ctrl,
.s_ctrl = v4l2_subdev_s_ctrl,
.queryctrl = v4l2_subdev_queryctrl,
.querymenu = v4l2_subdev_querymenu,
};
static const struct v4l2_subdev_audio_ops wm8739_audio_ops = {
@ -272,7 +265,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id);
static struct i2c_driver wm8739_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "wm8739",
},
.probe = wm8739_probe,

View file

@ -318,7 +318,6 @@ MODULE_DEVICE_TABLE(i2c, wm8775_id);
static struct i2c_driver wm8775_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "wm8775",
},
.probe = wm8775_probe,

View file

@ -282,9 +282,9 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
if (ret < 0 && ret != -ENOIOCTLCMD) {
dev_dbg(entity->parent->dev,
"link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n",
entity->name, link->source->index,
link->sink->entity->name,
link->sink->index, ret);
link->source->entity->name,
link->source->index,
entity->name, link->sink->index, ret);
goto error;
}
}

View file

@ -11,16 +11,16 @@ if MEDIA_PCI_SUPPORT
if MEDIA_CAMERA_SUPPORT
comment "Media capture support"
source "drivers/media/pci/meye/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/sta2x11/Kconfig"
source "drivers/media/pci/tw68/Kconfig"
source "drivers/media/pci/zoran/Kconfig"
endif
if MEDIA_ANALOG_TV_SUPPORT
comment "Media capture/analog TV support"
source "drivers/media/pci/ivtv/Kconfig"
source "drivers/media/pci/zoran/Kconfig"
source "drivers/media/pci/saa7146/Kconfig"
source "drivers/media/pci/solo6x10/Kconfig"
source "drivers/media/pci/tw68/Kconfig"
source "drivers/media/pci/dt3155/Kconfig"
endif
@ -49,6 +49,7 @@ source "drivers/media/pci/mantis/Kconfig"
source "drivers/media/pci/ngene/Kconfig"
source "drivers/media/pci/ddbridge/Kconfig"
source "drivers/media/pci/smipcie/Kconfig"
source "drivers/media/pci/netup_unidvb/Kconfig"
endif
endif #MEDIA_PCI_SUPPORT

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