/*
* tvp5150 - Texas Instruments TVP5150A/AM1 video decoder driver
*
* Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
* This code is placed under the terms of the GNU General Public License v2
*/
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
#include <media/v4l2-device.h>
#include <media/tvp5150.h>
#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ctrls.h>
#include "tvp5150_reg.h"
MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver");
MODULE_AUTHOR("Mauro Carvalho Chehab");
MODULE_LICENSE("GPL");
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-2)");
struct tvp5150 {
struct v4l2_subdev sd;
struct v4l2_ctrl_handler hdl;
v4l2_std_id norm; /* Current set standard */
u32 input;
u32 output;
int enable;
};
static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
{
return container_of(sd, struct tvp5150, sd);
}
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{
return &container_of(ctrl->handler, struct tvp5150, hdl)->sd;
}
static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
{
struct i2c_client *c = v4l2_get_subdevdata(sd);
unsigned char buffer[1];
int rc;
buffer[0] = addr;
if (1 != (rc = i2c_master_send(c, buffer, 1)))
v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
msleep(10);
if (1 != (rc = i2c_master_recv(c, buffer, 1)))
v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 1)\n", rc);
v4l2_dbg(2, debug, sd, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]);
return (buffer[0]);
}
static inline void tvp5150_write(struct v4l2_subdev *sd, unsigned char addr,
unsigned char value)
{
struct i2c_client *c = v4l2_get_subdevdata(sd);
unsigned char buffer[2];
int rc;
buffer[0] = addr;
buffer[1] = value;
v4l2_dbg(2, debug, sd, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
if (2 != (rc = i2c_master_send(c, buffer, 2)))
v4l2_dbg(0, debug, sd, "i2c i/o error: rc == %d (should be 2)\n", rc);
}
static void dump_reg_range(struct v4l2_subdev *sd, char *s, u8 init,
const u8 end, int max_line)
{
int i = 0;
while (init != (u8)(end + 1)) {
if ((i % max_line) == 0) {
if (i > 0)
printk("\n");
printk("tvp5150: %s reg 0x%02x = ", s, init);
}
printk("%02x ", tvp5150_read(sd, init));
init++;
i++;
}
printk("\n");
}
static int tvp5150_log_status(struct v4l2_subdev *sd)
{
printk("tvp5150: Video input source selection #1 = 0x%02x\n",
tvp5150_read(sd, TVP5150_VD_IN_SRC_SEL_1));
printk("tvp5150: Analog channel controls = 0x%02x\n",
tvp5150_read(sd, TVP5150_ANAL_CHL_CTL));
printk("tvp5150: Operation mode controls = 0x%02x\n",
tvp5150_read(sd, TVP5150_OP_MODE_CTL));
printk("tvp5150: Miscellaneous controls = 0x%02x\n",
tvp5150_read(sd, TVP5150_MISC_CTL));
printk("tvp5150: Autoswitch mask= 0x%02x\n",
tvp5150_read(sd, TVP5150_AUTOSW_MSK));
printk("tvp5150: Color killer threshold control = 0x%02x\n",
tvp5150_read(sd, TVP5150_COLOR_KIL_THSH_CTL));
printk("tvp5150: Luminance processing controls #1 #2 and #3 = %02x %02x %02x\n",
tvp5150_read