Merge tag 'media/v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - new framework support for HDMI CEC and remote control support - new encoding codec driver for Mediatek SoC - new frontend driver: helene tuner - added support for NetUp almost universal devices, with supports DVB-C/S/S2/T/T2 and ISDB-T - the mn88472 frontend driver got promoted from staging - a new driver for RCar video input - some soc_camera legacy drivers got removed: timb, omap1, mx2, mx3 - lots of driver cleanups, improvements and fixups * tag 'media/v4.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (377 commits) [media] cec: always check all_device_types and features [media] cec: poll should check if there is room in the tx queue [media] vivid: support monitor all mode [media] cec: fix test for unconfigured adapter in main message loop [media] cec: limit the size of the transmit queue [media] cec: zero unused msg part after msg->len [media] cec: don't set fh to NULL in CEC_TRANSMIT [media] cec: clear all status fields before transmit and always fill in sequence [media] cec: CEC_RECEIVE overwrote the timeout field [media] cxd2841er: Reading SNR for DVB-C added [media] cxd2841er: Reading BER and UCB for DVB-C added [media] cxd2841er: fix switch-case for DVB-C [media] cxd2841er: fix signal strength scale for ISDB-T [media] cxd2841er: adjust the dB scale for DVB-C [media] cxd2841er: provide signal strength for DVB-C [media] cxd2841er: fix BER report via DVBv5 stats API [media] mb86a20s: apply mask to val after checking for read failure [media] airspy: fix error logic during device register [media] s5p-cec/TODO: add TODO item [media] cec/TODO: drop comment about sphinx documentation ...
This commit is contained in:
@@ -488,7 +488,7 @@ static void airspy_disconnect(struct usb_interface *intf)
|
||||
/* Videobuf2 operations */
|
||||
static int airspy_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers,
|
||||
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct airspy *s = vb2_get_drv_priv(vq);
|
||||
|
||||
|
@@ -142,7 +142,7 @@ static void au0828_unregister_media_device(struct au0828_dev *dev)
|
||||
struct media_device *mdev = dev->media_dev;
|
||||
struct media_entity_notify *notify, *nextp;
|
||||
|
||||
if (!mdev || !media_devnode_is_registered(&mdev->devnode))
|
||||
if (!mdev || !media_devnode_is_registered(mdev->devnode))
|
||||
return;
|
||||
|
||||
/* Remove au0828 entity_notify callbacks */
|
||||
@@ -482,7 +482,7 @@ static int au0828_media_device_register(struct au0828_dev *dev,
|
||||
if (!dev->media_dev)
|
||||
return 0;
|
||||
|
||||
if (!media_devnode_is_registered(&dev->media_dev->devnode)) {
|
||||
if (!media_devnode_is_registered(dev->media_dev->devnode)) {
|
||||
|
||||
/* register media device */
|
||||
ret = media_device_register(dev->media_dev);
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
static int vbi_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct au0828_dev *dev = vb2_get_drv_priv(vq);
|
||||
unsigned long size = dev->vbi_width * dev->vbi_height * 2;
|
||||
|
@@ -698,7 +698,7 @@ int au0828_v4l2_device_register(struct usb_interface *interface,
|
||||
|
||||
static int queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct au0828_dev *dev = vb2_get_drv_priv(vq);
|
||||
unsigned long size = dev->height * dev->bytesperline;
|
||||
|
@@ -1570,10 +1570,12 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
||||
{
|
||||
struct cx231xx_fh *fh = file->private_data;
|
||||
struct cx231xx *dev = fh->dev;
|
||||
struct v4l2_subdev *sd;
|
||||
|
||||
dprintk(3, "enter vidioc_s_ctrl()\n");
|
||||
/* Update the A/V core */
|
||||
call_all(dev, core, s_ctrl, ctl);
|
||||
v4l2_device_for_each_subdev(sd, &dev->v4l2_dev)
|
||||
v4l2_s_ctrl(NULL, sd->ctrl_handler, ctl);
|
||||
dprintk(3, "exit vidioc_s_ctrl()\n");
|
||||
return 0;
|
||||
}
|
||||
|
@@ -127,17 +127,22 @@ config DVB_USB_MXL111SF
|
||||
config DVB_USB_RTL28XXU
|
||||
tristate "Realtek RTL28xxU DVB USB support"
|
||||
depends on DVB_USB_V2 && I2C_MUX
|
||||
select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_RTL2830
|
||||
select DVB_RTL2832
|
||||
select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT)
|
||||
select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_FC0012 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_FC0013 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_FC2580 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_MXL5005S if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_R820T if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_SI2157 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select MEDIA_TUNER_TUA9001 if MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y here to support the Realtek RTL28xxU DVB USB receiver.
|
||||
|
||||
|
@@ -49,6 +49,7 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
|
||||
#define CHECKSUM_LEN 2
|
||||
#define USB_TIMEOUT 2000
|
||||
struct state *state = d_to_priv(d);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret, wlen, rlen;
|
||||
u16 checksum, tmp_checksum;
|
||||
|
||||
@@ -57,8 +58,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
|
||||
/* buffer overflow check */
|
||||
if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
|
||||
req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
|
||||
dev_err(&d->udev->dev, "%s: too much data wlen=%d rlen=%d\n",
|
||||
KBUILD_MODNAME, req->wlen, req->rlen);
|
||||
dev_err(&intf->dev, "too much data wlen=%d rlen=%d\n",
|
||||
req->wlen, req->rlen);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
@@ -94,10 +95,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
|
||||
checksum = af9035_checksum(state->buf, rlen - 2);
|
||||
tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1];
|
||||
if (tmp_checksum != checksum) {
|
||||
dev_err(&d->udev->dev,
|
||||
"%s: command=%02x checksum mismatch (%04x != %04x)\n",
|
||||
KBUILD_MODNAME, req->cmd, tmp_checksum,
|
||||
checksum);
|
||||
dev_err(&intf->dev, "command=%02x checksum mismatch (%04x != %04x)\n",
|
||||
req->cmd, tmp_checksum, checksum);
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
@@ -110,8 +109,8 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: command=%02x failed fw error=%d\n",
|
||||
__func__, req->cmd, state->buf[2]);
|
||||
dev_dbg(&intf->dev, "command=%02x failed fw error=%d\n",
|
||||
req->cmd, state->buf[2]);
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
@@ -122,20 +121,20 @@ static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
|
||||
exit:
|
||||
mutex_unlock(&d->usb_mutex);
|
||||
if (ret < 0)
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* write multiple registers */
|
||||
static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
u8 wbuf[MAX_XFER_SIZE];
|
||||
u8 mbox = (reg >> 16) & 0xff;
|
||||
struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL };
|
||||
|
||||
if (6 + len > sizeof(wbuf)) {
|
||||
dev_warn(&d->udev->dev, "%s: i2c wr: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, len);
|
||||
dev_warn(&intf->dev, "i2c wr: len=%d is too big!\n", len);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -198,6 +197,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
|
||||
{
|
||||
int ret, num;
|
||||
struct state *state = d_to_priv(d);
|
||||
struct usb_interface *intf = d->intf;
|
||||
struct i2c_client *client;
|
||||
struct i2c_board_info board_info = {
|
||||
.addr = addr,
|
||||
@@ -212,11 +212,10 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: num=%d\n", __func__, num);
|
||||
dev_dbg(&intf->dev, "num=%d\n", num);
|
||||
|
||||
if (num == AF9035_I2C_CLIENT_MAX) {
|
||||
dev_err(&d->udev->dev, "%s: I2C client out of index\n",
|
||||
KBUILD_MODNAME);
|
||||
dev_err(&intf->dev, "I2C client out of index\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
@@ -240,7 +239,7 @@ static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
|
||||
state->i2c_client[num] = client;
|
||||
return 0;
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -248,6 +247,7 @@ static void af9035_del_i2c_dev(struct dvb_usb_device *d)
|
||||
{
|
||||
int num;
|
||||
struct state *state = d_to_priv(d);
|
||||
struct usb_interface *intf = d->intf;
|
||||
struct i2c_client *client;
|
||||
|
||||
/* find last used client */
|
||||
@@ -257,11 +257,10 @@ static void af9035_del_i2c_dev(struct dvb_usb_device *d)
|
||||
break;
|
||||
}
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: num=%d\n", __func__, num);
|
||||
dev_dbg(&intf->dev, "num=%d\n", num);
|
||||
|
||||
if (num == -1) {
|
||||
dev_err(&d->udev->dev, "%s: I2C client out of index\n",
|
||||
KBUILD_MODNAME);
|
||||
dev_err(&intf->dev, "I2C client out of index\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -276,7 +275,7 @@ static void af9035_del_i2c_dev(struct dvb_usb_device *d)
|
||||
state->i2c_client[num] = NULL;
|
||||
return;
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed\n", __func__);
|
||||
dev_dbg(&intf->dev, "failed\n");
|
||||
}
|
||||
|
||||
static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
|
||||
@@ -348,6 +347,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
|
||||
|
||||
ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
|
||||
msg[1].len);
|
||||
} else if (state->no_read) {
|
||||
memset(msg[1].buf, 0, msg[1].len);
|
||||
ret = 0;
|
||||
} else {
|
||||
/* I2C write + read */
|
||||
u8 buf[MAX_XFER_SIZE];
|
||||
@@ -367,10 +369,25 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
|
||||
memcpy(&buf[3], msg[0].buf, msg[0].len);
|
||||
} else {
|
||||
buf[1] = msg[0].addr << 1;
|
||||
buf[2] = 0x00; /* reg addr len */
|
||||
buf[3] = 0x00; /* reg addr MSB */
|
||||
buf[4] = 0x00; /* reg addr LSB */
|
||||
memcpy(&buf[5], msg[0].buf, msg[0].len);
|
||||
|
||||
/* Keep prev behavior for write req len > 2*/
|
||||
if (msg[0].len > 2) {
|
||||
buf[2] = 0x00; /* reg addr len */
|
||||
memcpy(&buf[5], msg[0].buf, msg[0].len);
|
||||
|
||||
/* Use reg addr fields if write req len <= 2 */
|
||||
} else {
|
||||
req.wlen = 5;
|
||||
buf[2] = msg[0].len;
|
||||
if (msg[0].len == 2) {
|
||||
buf[3] = msg[0].buf[0];
|
||||
buf[4] = msg[0].buf[1];
|
||||
} else if (msg[0].len == 1) {
|
||||
buf[4] = msg[0].buf[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = af9035_ctrl_msg(d, &req);
|
||||
}
|
||||
@@ -421,6 +438,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
|
||||
if (msg[0].len > 40) {
|
||||
/* TODO: correct limits > 40 */
|
||||
ret = -EOPNOTSUPP;
|
||||
} else if (state->no_read) {
|
||||
memset(msg[0].buf, 0, msg[0].len);
|
||||
ret = 0;
|
||||
} else {
|
||||
/* I2C read */
|
||||
u8 buf[5];
|
||||
@@ -475,7 +495,9 @@ static struct i2c_algorithm af9035_i2c_algo = {
|
||||
static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
|
||||
{
|
||||
struct state *state = d_to_priv(d);
|
||||
int ret;
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret, ts_mode_invalid;
|
||||
u8 tmp;
|
||||
u8 wbuf[1] = { 1 };
|
||||
u8 rbuf[4];
|
||||
struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
|
||||
@@ -492,10 +514,8 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
dev_info(&d->udev->dev,
|
||||
"%s: prechip_version=%02x chip_version=%02x chip_type=%04x\n",
|
||||
KBUILD_MODNAME, state->prechip_version,
|
||||
state->chip_version, state->chip_type);
|
||||
dev_info(&intf->dev, "prechip_version=%02x chip_version=%02x chip_type=%04x\n",
|
||||
state->prechip_version, state->chip_version, state->chip_type);
|
||||
|
||||
if (state->chip_type == 0x9135) {
|
||||
if (state->chip_version == 0x02)
|
||||
@@ -511,11 +531,41 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
|
||||
state->eeprom_addr = EEPROM_BASE_AF9035;
|
||||
}
|
||||
|
||||
|
||||
/* check for dual tuner mode */
|
||||
ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ts_mode_invalid = 0;
|
||||
switch (tmp) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
state->dual_mode = true;
|
||||
break;
|
||||
case 5:
|
||||
if (state->chip_type != 0x9135 && state->chip_type != 0x9306)
|
||||
state->dual_mode = true; /* AF9035 */
|
||||
else
|
||||
ts_mode_invalid = 1;
|
||||
break;
|
||||
default:
|
||||
ts_mode_invalid = 1;
|
||||
}
|
||||
|
||||
dev_dbg(&intf->dev, "ts mode=%d dual mode=%d\n", tmp, state->dual_mode);
|
||||
|
||||
if (ts_mode_invalid)
|
||||
dev_info(&intf->dev, "ts mode=%d not supported, defaulting to single tuner mode!", tmp);
|
||||
|
||||
|
||||
ret = af9035_ctrl_msg(d, &req);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: reply=%*ph\n", __func__, 4, rbuf);
|
||||
dev_dbg(&intf->dev, "reply=%*ph\n", 4, rbuf);
|
||||
if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
|
||||
ret = WARM;
|
||||
else
|
||||
@@ -524,7 +574,7 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
|
||||
return ret;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -532,6 +582,7 @@ err:
|
||||
static int af9035_download_firmware_old(struct dvb_usb_device *d,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret, i, j, len;
|
||||
u8 wbuf[1];
|
||||
struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
|
||||
@@ -562,14 +613,12 @@ static int af9035_download_firmware_old(struct dvb_usb_device *d,
|
||||
hdr_checksum = fw->data[fw->size - i + 5] << 8;
|
||||
hdr_checksum |= fw->data[fw->size - i + 6] << 0;
|
||||
|
||||
dev_dbg(&d->udev->dev,
|
||||
"%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
|
||||
__func__, hdr_core, hdr_addr, hdr_data_len,
|
||||
hdr_checksum);
|
||||
dev_dbg(&intf->dev, "core=%d addr=%04x data_len=%d checksum=%04x\n",
|
||||
hdr_core, hdr_addr, hdr_data_len, hdr_checksum);
|
||||
|
||||
if (((hdr_core != 1) && (hdr_core != 2)) ||
|
||||
(hdr_data_len > i)) {
|
||||
dev_dbg(&d->udev->dev, "%s: bad firmware\n", __func__);
|
||||
dev_dbg(&intf->dev, "bad firmware\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -600,18 +649,17 @@ static int af9035_download_firmware_old(struct dvb_usb_device *d,
|
||||
|
||||
i -= hdr_data_len + HDR_SIZE;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: data uploaded=%zu\n",
|
||||
__func__, fw->size - i);
|
||||
dev_dbg(&intf->dev, "data uploaded=%zu\n", fw->size - i);
|
||||
}
|
||||
|
||||
/* print warn if firmware is bad, continue and see what happens */
|
||||
if (i)
|
||||
dev_warn(&d->udev->dev, "%s: bad firmware\n", KBUILD_MODNAME);
|
||||
dev_warn(&intf->dev, "bad firmware\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -619,6 +667,7 @@ err:
|
||||
static int af9035_download_firmware_new(struct dvb_usb_device *d,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret, i, i_prev;
|
||||
struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
|
||||
#define HDR_SIZE 7
|
||||
@@ -648,15 +697,14 @@ static int af9035_download_firmware_new(struct dvb_usb_device *d,
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: data uploaded=%d\n",
|
||||
__func__, i);
|
||||
dev_dbg(&intf->dev, "data uploaded=%d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -664,6 +712,7 @@ err:
|
||||
static int af9035_download_firmware(struct dvb_usb_device *d,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
struct state *state = d_to_priv(d);
|
||||
int ret;
|
||||
u8 wbuf[1];
|
||||
@@ -672,7 +721,7 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
|
||||
struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
|
||||
struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf };
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s:\n", __func__);
|
||||
dev_dbg(&intf->dev, "\n");
|
||||
|
||||
/*
|
||||
* In case of dual tuner configuration we need to do some extra
|
||||
@@ -680,11 +729,7 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
|
||||
* which is done by master demod.
|
||||
* Master feeds also clock and controls power via GPIO.
|
||||
*/
|
||||
ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (tmp == 1 || tmp == 3 || tmp == 5) {
|
||||
if (state->dual_mode) {
|
||||
/* configure gpioh1, reset & power slave demod */
|
||||
ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01);
|
||||
if (ret < 0)
|
||||
@@ -752,25 +797,25 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
|
||||
goto err;
|
||||
|
||||
if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
|
||||
dev_err(&d->udev->dev, "%s: firmware did not run\n",
|
||||
KBUILD_MODNAME);
|
||||
dev_err(&intf->dev, "firmware did not run\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev_info(&d->udev->dev, "%s: firmware version=%d.%d.%d.%d",
|
||||
KBUILD_MODNAME, rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
|
||||
dev_info(&intf->dev, "firmware version=%d.%d.%d.%d",
|
||||
rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int af9035_read_config(struct dvb_usb_device *d)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
struct state *state = d_to_priv(d);
|
||||
int ret, i;
|
||||
u8 tmp;
|
||||
@@ -805,7 +850,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
goto err;
|
||||
|
||||
if (tmp == 0x00) {
|
||||
dev_dbg(&d->udev->dev, "%s: no eeprom\n", __func__);
|
||||
dev_dbg(&intf->dev, "no eeprom\n");
|
||||
goto skip_eeprom;
|
||||
}
|
||||
} else if (state->chip_type == 0x9306) {
|
||||
@@ -817,18 +862,6 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* check if there is dual tuners */
|
||||
ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (tmp == 1 || tmp == 3 || tmp == 5)
|
||||
state->dual_mode = true;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: ts mode=%d dual mode=%d\n", __func__,
|
||||
tmp, state->dual_mode);
|
||||
|
||||
if (state->dual_mode) {
|
||||
/* read 2nd demodulator I2C address */
|
||||
ret = af9035_rd_reg(d,
|
||||
@@ -840,8 +873,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
if (tmp)
|
||||
state->af9033_i2c_addr[1] = tmp;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: 2nd demod I2C addr=%02x\n",
|
||||
__func__, tmp);
|
||||
dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n", tmp);
|
||||
}
|
||||
|
||||
addr = state->eeprom_addr;
|
||||
@@ -852,8 +884,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: [%d]tuner=%02x\n",
|
||||
__func__, i, tmp);
|
||||
dev_dbg(&intf->dev, "[%d]tuner=%02x\n", i, tmp);
|
||||
|
||||
/* tuner sanity check */
|
||||
if (state->chip_type == 0x9135) {
|
||||
@@ -882,10 +913,8 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
}
|
||||
|
||||
if (state->af9033_config[i].tuner != tmp) {
|
||||
dev_info(&d->udev->dev,
|
||||
"%s: [%d] overriding tuner from %02x to %02x\n",
|
||||
KBUILD_MODNAME, i, tmp,
|
||||
state->af9033_config[i].tuner);
|
||||
dev_info(&intf->dev, "[%d] overriding tuner from %02x to %02x\n",
|
||||
i, tmp, state->af9033_config[i].tuner);
|
||||
}
|
||||
|
||||
switch (state->af9033_config[i].tuner) {
|
||||
@@ -905,9 +934,8 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
case AF9033_TUNER_IT9135_62:
|
||||
break;
|
||||
default:
|
||||
dev_warn(&d->udev->dev,
|
||||
"%s: tuner id=%02x not supported, please report!",
|
||||
KBUILD_MODNAME, tmp);
|
||||
dev_warn(&intf->dev, "tuner id=%02x not supported, please report!",
|
||||
tmp);
|
||||
}
|
||||
|
||||
/* disable dual mode if driver does not support it */
|
||||
@@ -924,9 +952,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
break;
|
||||
default:
|
||||
state->dual_mode = false;
|
||||
dev_info(&d->udev->dev,
|
||||
"%s: driver does not support 2nd tuner and will disable it",
|
||||
KBUILD_MODNAME);
|
||||
dev_info(&intf->dev, "driver does not support 2nd tuner and will disable it");
|
||||
}
|
||||
|
||||
/* tuner IF frequency */
|
||||
@@ -942,7 +968,7 @@ static int af9035_read_config(struct dvb_usb_device *d)
|
||||
|
||||
tmp16 |= tmp << 8;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: [%d]IF=%d\n", __func__, i, tmp16);
|
||||
dev_dbg(&intf->dev, "[%d]IF=%d\n", i, tmp16);
|
||||
|
||||
addr += 0x10; /* shift for the 2nd tuner params */
|
||||
}
|
||||
@@ -962,10 +988,24 @@ skip_eeprom:
|
||||
state->af9033_config[i].clock = clock_lut_af9035[tmp];
|
||||
}
|
||||
|
||||
state->no_read = false;
|
||||
/* Some MXL5007T devices cannot properly handle tuner I2C read ops. */
|
||||
if (state->af9033_config[0].tuner == AF9033_TUNER_MXL5007T &&
|
||||
le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA)
|
||||
|
||||
switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
|
||||
case USB_PID_AVERMEDIA_A867:
|
||||
case USB_PID_AVERMEDIA_TWINSTAR:
|
||||
dev_info(&intf->dev,
|
||||
"Device may have issues with I2C read operations. Enabling fix.\n");
|
||||
state->no_read = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -973,10 +1013,11 @@ err:
|
||||
static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d,
|
||||
int cmd, int arg)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
|
||||
dev_dbg(&intf->dev, "cmd=%d arg=%d\n", cmd, arg);
|
||||
|
||||
/*
|
||||
* CEN always enabled by hardware wiring
|
||||
@@ -1010,7 +1051,7 @@ static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1019,6 +1060,7 @@ err:
|
||||
static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
|
||||
int cmd, int arg)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
@@ -1076,7 +1118,7 @@ static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1102,9 +1144,10 @@ static int af9035_frontend_callback(void *adapter_priv, int component,
|
||||
{
|
||||
struct i2c_adapter *adap = adapter_priv;
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: component=%d cmd=%d arg=%d\n",
|
||||
__func__, component, cmd, arg);
|
||||
dev_dbg(&intf->dev, "component=%d cmd=%d arg=%d\n",
|
||||
component, cmd, arg);
|
||||
|
||||
switch (component) {
|
||||
case DVB_FRONTEND_COMPONENT_TUNER:
|
||||
@@ -1127,9 +1170,10 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
if (!state->af9033_config[adap->id].tuner) {
|
||||
/* unsupported tuner */
|
||||
@@ -1156,7 +1200,7 @@ static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1165,11 +1209,12 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
struct si2168_config si2168_config;
|
||||
struct i2c_adapter *adapter;
|
||||
|
||||
dev_dbg(&d->udev->dev, "adap->id=%d\n", adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
memset(&si2168_config, 0, sizeof(si2168_config));
|
||||
si2168_config.i2c_adapter = &adapter;
|
||||
@@ -1192,7 +1237,7 @@ static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1201,9 +1246,10 @@ static int af9035_frontend_detach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int demod2;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
/*
|
||||
* For dual tuner devices we have to resolve 2nd demod client, as there
|
||||
@@ -1279,12 +1325,13 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
struct dvb_frontend *fe;
|
||||
struct i2c_msg msg[1];
|
||||
u8 tuner_addr;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
/*
|
||||
* XXX: Hack used in that function: we abuse unused I2C address bit [7]
|
||||
@@ -1522,7 +1569,7 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1531,10 +1578,11 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
struct si2157_config si2157_config;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
/* I2C master bus 2 clock speed 300k */
|
||||
ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
|
||||
@@ -1590,7 +1638,7 @@ static int it930x_tuner_attach(struct dvb_usb_adapter *adap)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1600,8 +1648,9 @@ static int it930x_tuner_detach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
|
||||
dev_dbg(&d->udev->dev, "adap->id=%d\n", adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
if (adap->id == 1) {
|
||||
if (state->i2c_client[3])
|
||||
@@ -1619,8 +1668,9 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
struct state *state = adap_to_priv(adap);
|
||||
struct dvb_usb_device *d = adap_to_d(adap);
|
||||
struct usb_interface *intf = d->intf;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: adap->id=%d\n", __func__, adap->id);
|
||||
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
|
||||
|
||||
switch (state->af9033_config[adap->id].tuner) {
|
||||
case AF9033_TUNER_TUA9001:
|
||||
@@ -1646,6 +1696,7 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
|
||||
static int af9035_init(struct dvb_usb_device *d)
|
||||
{
|
||||
struct state *state = d_to_priv(d);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret, i;
|
||||
u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4;
|
||||
u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
|
||||
@@ -1670,9 +1721,8 @@ static int af9035_init(struct dvb_usb_device *d)
|
||||
{ 0x80f9a4, 0x00, 0x01 },
|
||||
};
|
||||
|
||||
dev_dbg(&d->udev->dev,
|
||||
"%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
|
||||
__func__, d->udev->speed, frame_size, packet_size);
|
||||
dev_dbg(&intf->dev, "USB speed=%d frame_size=%04x packet_size=%02x\n",
|
||||
d->udev->speed, frame_size, packet_size);
|
||||
|
||||
/* init endpoints */
|
||||
for (i = 0; i < ARRAY_SIZE(tab); i++) {
|
||||
@@ -1685,7 +1735,7 @@ static int af9035_init(struct dvb_usb_device *d)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1693,6 +1743,7 @@ err:
|
||||
static int it930x_init(struct dvb_usb_device *d)
|
||||
{
|
||||
struct state *state = d_to_priv(d);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret, i;
|
||||
u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 816) * 188 / 4;
|
||||
u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
|
||||
@@ -1752,9 +1803,8 @@ static int it930x_init(struct dvb_usb_device *d)
|
||||
{ 0x00da5a, 0x1f, 0xff }, /* ts_fail_ignore */
|
||||
};
|
||||
|
||||
dev_dbg(&d->udev->dev,
|
||||
"%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
|
||||
__func__, d->udev->speed, frame_size, packet_size);
|
||||
dev_dbg(&intf->dev, "USB speed=%d frame_size=%04x packet_size=%02x\n",
|
||||
d->udev->speed, frame_size, packet_size);
|
||||
|
||||
/* init endpoints */
|
||||
for (i = 0; i < ARRAY_SIZE(tab); i++) {
|
||||
@@ -1767,7 +1817,7 @@ static int it930x_init(struct dvb_usb_device *d)
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1776,6 +1826,7 @@ err:
|
||||
#if IS_ENABLED(CONFIG_RC_CORE)
|
||||
static int af9035_rc_query(struct dvb_usb_device *d)
|
||||
{
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
u32 key;
|
||||
u8 buf[4];
|
||||
@@ -1801,14 +1852,14 @@ static int af9035_rc_query(struct dvb_usb_device *d)
|
||||
buf[2] << 8 | buf[3]);
|
||||
}
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: %*ph\n", __func__, 4, buf);
|
||||
dev_dbg(&intf->dev, "%*ph\n", 4, buf);
|
||||
|
||||
rc_keydown(d->rc_dev, RC_TYPE_NEC, key, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1816,6 +1867,7 @@ err:
|
||||
static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
|
||||
{
|
||||
struct state *state = d_to_priv(d);
|
||||
struct usb_interface *intf = d->intf;
|
||||
int ret;
|
||||
u8 tmp;
|
||||
|
||||
@@ -1823,7 +1875,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: ir_mode=%02x\n", __func__, tmp);
|
||||
dev_dbg(&intf->dev, "ir_mode=%02x\n", tmp);
|
||||
|
||||
/* don't activate rc if in HID mode or if not available */
|
||||
if (tmp == 5) {
|
||||
@@ -1832,7 +1884,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: ir_type=%02x\n", __func__, tmp);
|
||||
dev_dbg(&intf->dev, "ir_type=%02x\n", tmp);
|
||||
|
||||
switch (tmp) {
|
||||
case 0: /* NEC */
|
||||
@@ -1855,7 +1907,7 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
|
||||
dev_dbg(&intf->dev, "failed=%d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1867,8 +1919,9 @@ static int af9035_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
|
||||
struct usb_data_stream_properties *stream)
|
||||
{
|
||||
struct dvb_usb_device *d = fe_to_d(fe);
|
||||
struct usb_interface *intf = d->intf;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
|
||||
dev_dbg(&intf->dev, "adap=%d\n", fe_to_adap(fe)->id);
|
||||
|
||||
if (d->udev->speed == USB_SPEED_FULL)
|
||||
stream->u.bulk.buffersize = 5 * 188;
|
||||
@@ -1920,7 +1973,7 @@ static int af9035_probe(struct usb_interface *intf,
|
||||
if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) &&
|
||||
(le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) {
|
||||
if (!strcmp("Afatech", manufacturer)) {
|
||||
dev_dbg(&udev->dev, "%s: rejecting device\n", __func__);
|
||||
dev_dbg(&udev->dev, "rejecting device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@ struct state {
|
||||
u8 chip_version;
|
||||
u16 chip_type;
|
||||
u8 dual_mode:1;
|
||||
u8 no_read:1;
|
||||
u16 eeprom_addr;
|
||||
u8 af9033_i2c_addr[2];
|
||||
struct af9033_config af9033_config[2];
|
||||
@@ -112,7 +113,7 @@ static const u32 clock_lut_it9135[] = {
|
||||
* 0 TS
|
||||
* 1 DCA + PIP
|
||||
* 3 PIP
|
||||
* 5 DCA + PIP
|
||||
* 5 DCA + PIP (AF9035 only)
|
||||
* n DCA
|
||||
*
|
||||
* Values 0, 3 and 5 are seen to this day. 0 for single TS and 3/5 for dual TS.
|
||||
|
@@ -624,7 +624,7 @@ static int rtl28xxu_identify_state(struct dvb_usb_device *d, const char **name)
|
||||
dev_dbg(&d->intf->dev, "chip_id=%u\n", dev->chip_id);
|
||||
|
||||
/* Retry failed I2C messages */
|
||||
d->i2c_adap.retries = 1;
|
||||
d->i2c_adap.retries = 3;
|
||||
d->i2c_adap.timeout = msecs_to_jiffies(10);
|
||||
|
||||
return WARM;
|
||||
|
@@ -55,36 +55,36 @@ static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
|
||||
return dvb_usb_generic_write(adap->dev, b_pid, 4);
|
||||
}
|
||||
|
||||
/* remote control */
|
||||
/* key list for the tiny remote control (Yakumo, don't know about the others) */
|
||||
static struct rc_map_table rc_map_dtt200u_table[] = {
|
||||
{ 0x8001, KEY_MUTE },
|
||||
{ 0x8002, KEY_CHANNELDOWN },
|
||||
{ 0x8003, KEY_VOLUMEDOWN },
|
||||
{ 0x8004, KEY_1 },
|
||||
{ 0x8005, KEY_2 },
|
||||
{ 0x8006, KEY_3 },
|
||||
{ 0x8007, KEY_4 },
|
||||
{ 0x8008, KEY_5 },
|
||||
{ 0x8009, KEY_6 },
|
||||
{ 0x800a, KEY_7 },
|
||||
{ 0x800c, KEY_ZOOM },
|
||||
{ 0x800d, KEY_0 },
|
||||
{ 0x800e, KEY_SELECT },
|
||||
{ 0x8012, KEY_POWER },
|
||||
{ 0x801a, KEY_CHANNELUP },
|
||||
{ 0x801b, KEY_8 },
|
||||
{ 0x801e, KEY_VOLUMEUP },
|
||||
{ 0x801f, KEY_9 },
|
||||
};
|
||||
|
||||
static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
|
||||
static int dtt200u_rc_query(struct dvb_usb_device *d)
|
||||
{
|
||||
u8 key[5],cmd = GET_RC_CODE;
|
||||
u32 scancode;
|
||||
|
||||
dvb_usb_generic_rw(d,&cmd,1,key,5,0);
|
||||
dvb_usb_nec_rc_key_to_event(d,key,event,state);
|
||||
if (key[0] == 1) {
|
||||
scancode = key[1];
|
||||
if ((u8) ~key[1] != key[2]) {
|
||||
/* Extended NEC */
|
||||
scancode = scancode << 8;
|
||||
scancode |= key[2];
|
||||
}
|
||||
scancode = scancode << 8;
|
||||
scancode |= key[3];
|
||||
|
||||
/* Check command checksum is ok */
|
||||
if ((u8) ~key[3] == key[4])
|
||||
rc_keydown(d->rc_dev, RC_TYPE_NEC, scancode, 0);
|
||||
else
|
||||
rc_keyup(d->rc_dev);
|
||||
} else if (key[0] == 2) {
|
||||
rc_repeat(d->rc_dev);
|
||||
} else {
|
||||
rc_keyup(d->rc_dev);
|
||||
}
|
||||
|
||||
if (key[0] != 0)
|
||||
deb_info("key: %*ph\n", 5, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -164,11 +164,11 @@ static struct dvb_usb_device_properties dtt200u_properties = {
|
||||
},
|
||||
.power_ctrl = dtt200u_power_ctrl,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.rc_interval = 300,
|
||||
.rc_map_table = rc_map_dtt200u_table,
|
||||
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
|
||||
.rc_codes = RC_MAP_DTT200U,
|
||||
.rc_query = dtt200u_rc_query,
|
||||
.allowed_protos = RC_BIT_NEC,
|
||||
},
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
@@ -214,11 +214,11 @@ static struct dvb_usb_device_properties wt220u_properties = {
|
||||
},
|
||||
.power_ctrl = dtt200u_power_ctrl,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.rc_interval = 300,
|
||||
.rc_map_table = rc_map_dtt200u_table,
|
||||
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
|
||||
.rc_codes = RC_MAP_DTT200U,
|
||||
.rc_query = dtt200u_rc_query,
|
||||
.allowed_protos = RC_BIT_NEC,
|
||||
},
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
@@ -264,11 +264,11 @@ static struct dvb_usb_device_properties wt220u_fc_properties = {
|
||||
},
|
||||
.power_ctrl = dtt200u_power_ctrl,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.rc_interval = 300,
|
||||
.rc_map_table = rc_map_dtt200u_table,
|
||||
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
|
||||
.rc_codes = RC_MAP_DTT200U,
|
||||
.rc_query = dtt200u_rc_query,
|
||||
.allowed_protos = RC_BIT_NEC,
|
||||
},
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
@@ -314,11 +314,11 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = {
|
||||
},
|
||||
.power_ctrl = dtt200u_power_ctrl,
|
||||
|
||||
.rc.legacy = {
|
||||
.rc.core = {
|
||||
.rc_interval = 300,
|
||||
.rc_map_table = rc_map_dtt200u_table,
|
||||
.rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
|
||||
.rc_codes = RC_MAP_DTT200U,
|
||||
.rc_query = dtt200u_rc_query,
|
||||
.allowed_protos = RC_BIT_NEC,
|
||||
},
|
||||
|
||||
.generic_bulk_ctrl_endpoint = 0x01,
|
||||
|
@@ -320,8 +320,6 @@ int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
|
||||
|
||||
adap->num_frontends_initialized++;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dvb_create_media_graph(&adap->dvb_adap, true);
|
||||
if (ret)
|
||||
|
@@ -847,7 +847,7 @@ static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
|
||||
struct dw2102_state *state = (struct dw2102_state *)d->priv;
|
||||
u8 obuf[] = {0xde, 0};
|
||||
|
||||
info("%s: %d, initialized %d\n", __func__, i, state->initialized);
|
||||
info("%s: %d, initialized %d", __func__, i, state->initialized);
|
||||
|
||||
if (i && !state->initialized) {
|
||||
state->initialized = 1;
|
||||
@@ -894,7 +894,7 @@ static int su3000_identify_state(struct usb_device *udev,
|
||||
struct dvb_usb_device_description **desc,
|
||||
int *cold)
|
||||
{
|
||||
info("%s\n", __func__);
|
||||
info("%s", __func__);
|
||||
|
||||
*cold = 0;
|
||||
return 0;
|
||||
@@ -1132,7 +1132,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
|
||||
tuner_ops->set_bandwidth = stb6100_set_bandw;
|
||||
tuner_ops->get_bandwidth = stb6100_get_bandw;
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached STV0900+STB6100!\n");
|
||||
info("Attached STV0900+STB6100!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1146,7 +1146,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
|
||||
&dw2104_stv6110_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached STV0900+STV6110A!\n");
|
||||
info("Attached STV0900+STV6110A!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1157,7 +1157,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe_adap[0].fe != NULL) {
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached cx24116!\n");
|
||||
info("Attached cx24116!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1168,7 +1168,7 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
|
||||
dvb_attach(ts2020_attach, d->fe_adap[0].fe,
|
||||
&dw2104_ts2020_config, &d->dev->i2c_adap);
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached DS3000!\n");
|
||||
info("Attached DS3000!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1187,7 +1187,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe_adap[0].fe != NULL) {
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached si21xx!\n");
|
||||
info("Attached si21xx!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1199,7 +1199,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
|
||||
if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached stv0288!\n");
|
||||
info("Attached stv0288!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1211,7 +1211,7 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
|
||||
&d->dev->i2c_adap);
|
||||
if (d->fe_adap[0].fe != NULL) {
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached stv0299!\n");
|
||||
info("Attached stv0299!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1223,7 +1223,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
|
||||
d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
|
||||
&d->dev->i2c_adap, 0x48);
|
||||
if (d->fe_adap[0].fe != NULL) {
|
||||
info("Attached tda10023!\n");
|
||||
info("Attached tda10023!");
|
||||
return 0;
|
||||
}
|
||||
return -EIO;
|
||||
@@ -1237,7 +1237,7 @@ static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
|
||||
if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
|
||||
&d->dev->i2c_adap)) {
|
||||
d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
|
||||
info("Attached zl100313+zl10039!\n");
|
||||
info("Attached zl100313+zl10039!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1262,7 +1262,7 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
|
||||
|
||||
dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
|
||||
|
||||
info("Attached stv0288+stb6000!\n");
|
||||
info("Attached stv0288+stb6000!");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1287,7 +1287,7 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
|
||||
|
||||
dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
|
||||
|
||||
info("Attached ds3000+ts2020!\n");
|
||||
info("Attached ds3000+ts2020!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1305,7 +1305,7 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
|
||||
|
||||
dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
|
||||
|
||||
info("Attached STV0900+STB6100A!\n");
|
||||
info("Attached STV0900+STB6100A!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1353,11 +1353,11 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d)
|
||||
if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
|
||||
&dw2104_ts2020_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
info("Attached DS3000/TS2020!\n");
|
||||
info("Attached DS3000/TS2020!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
info("Failed to attach DS3000/TS2020!\n");
|
||||
info("Failed to attach DS3000/TS2020!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -1402,12 +1402,12 @@ static int t220_frontend_attach(struct dvb_usb_adapter *d)
|
||||
if (d->fe_adap[0].fe != NULL) {
|
||||
if (dvb_attach(tda18271_attach, d->fe_adap[0].fe, 0x60,
|
||||
&d->dev->i2c_adap, &tda18271_config)) {
|
||||
info("Attached TDA18271HD/CXD2820R!\n");
|
||||
info("Attached TDA18271HD/CXD2820R!");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
info("Failed to attach TDA18271HD/CXD2820R!\n");
|
||||
info("Failed to attach TDA18271HD/CXD2820R!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -1428,11 +1428,11 @@ static int m88rs2000_frontend_attach(struct dvb_usb_adapter *d)
|
||||
if (dvb_attach(ts2020_attach, d->fe_adap[0].fe,
|
||||
&dw2104_ts2020_config,
|
||||
&d->dev->i2c_adap)) {
|
||||
info("Attached RS2000/TS2020!\n");
|
||||
info("Attached RS2000/TS2020!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
info("Failed to attach RS2000/TS2020!\n");
|
||||
info("Failed to attach RS2000/TS2020!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -1641,6 +1641,7 @@ enum dw2102_table_entry {
|
||||
TEVII_S421,
|
||||
TEVII_S632,
|
||||
TERRATEC_CINERGY_S2_R2,
|
||||
TERRATEC_CINERGY_S2_R3,
|
||||
GOTVIEW_SAT_HD,
|
||||
GENIATECH_T220,
|
||||
TECHNOTREND_S2_4600,
|
||||
@@ -1669,6 +1670,7 @@ static struct usb_device_id dw2102_table[] = {
|
||||
[TEVII_S421] = {USB_DEVICE(0x9022, USB_PID_TEVII_S421)},
|
||||
[TEVII_S632] = {USB_DEVICE(0x9022, USB_PID_TEVII_S632)},
|
||||
[TERRATEC_CINERGY_S2_R2] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R2)},
|
||||
[TERRATEC_CINERGY_S2_R3] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R3)},
|
||||
[GOTVIEW_SAT_HD] = {USB_DEVICE(0x1FE1, USB_PID_GOTVIEW_SAT_HD)},
|
||||
[GENIATECH_T220] = {USB_DEVICE(0x1f4d, 0xD220)},
|
||||
[TECHNOTREND_S2_4600] = {USB_DEVICE(USB_VID_TECHNOTREND,
|
||||
@@ -2083,7 +2085,7 @@ static struct dvb_usb_device_properties su3000_properties = {
|
||||
}},
|
||||
}
|
||||
},
|
||||
.num_device_descs = 5,
|
||||
.num_device_descs = 6,
|
||||
.devices = {
|
||||
{ "SU3000HD DVB-S USB2.0",
|
||||
{ &dw2102_table[GENIATECH_SU3000], NULL },
|
||||
@@ -2101,6 +2103,10 @@ static struct dvb_usb_device_properties su3000_properties = {
|
||||
{ &dw2102_table[TERRATEC_CINERGY_S2_R2], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "Terratec Cinergy S2 USB HD Rev.3",
|
||||
{ &dw2102_table[TERRATEC_CINERGY_S2_R3], NULL },
|
||||
{ NULL },
|
||||
},
|
||||
{ "GOTVIEW Satellite HD",
|
||||
{ &dw2102_table[GOTVIEW_SAT_HD], NULL },
|
||||
{ NULL },
|
||||
|
@@ -904,17 +904,6 @@ static struct tda18271_config c3tech_duo_tda18271_config = {
|
||||
.small_i2c = TDA18271_03_BYTE_CHUNK_INIT,
|
||||
};
|
||||
|
||||
static const struct m88ds3103_config pctv_461e_m88ds3103_config = {
|
||||
.i2c_addr = 0x68,
|
||||
.clock = 27000000,
|
||||
.i2c_wr_max = 33,
|
||||
.clock_out = 0,
|
||||
.ts_mode = M88DS3103_TS_PARALLEL,
|
||||
.ts_clk = 16000,
|
||||
.ts_clk_pol = 1,
|
||||
.agc = 0x99,
|
||||
};
|
||||
|
||||
static struct tda18271_std_map drx_j_std_map = {
|
||||
.atsc_6 = { .if_freq = 5000, .agc_mode = 3, .std = 0, .if_lvl = 1,
|
||||
.rfagc_top = 0x37, },
|
||||
|
@@ -507,9 +507,8 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
|
||||
if (dev->disconnected)
|
||||
return -ENODEV;
|
||||
|
||||
rc = rt_mutex_trylock(&dev->i2c_bus_lock);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (!rt_mutex_trylock(&dev->i2c_bus_lock))
|
||||
return -EAGAIN;
|
||||
|
||||
/* Switch I2C bus if needed */
|
||||
if (bus != dev->cur_i2c_bus &&
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
static int vbi_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct em28xx *dev = vb2_get_drv_priv(vq);
|
||||
struct em28xx_v4l2 *v4l2 = dev->v4l2;
|
||||
|
@@ -1013,7 +1013,7 @@ static void em28xx_v4l2_create_entities(struct em28xx *dev)
|
||||
|
||||
static int queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct em28xx *dev = vb2_get_drv_priv(vq);
|
||||
struct em28xx_v4l2 *v4l2 = dev->v4l2;
|
||||
|
@@ -370,7 +370,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
|
||||
static int go7007_queue_setup(struct vb2_queue *q,
|
||||
unsigned int *num_buffers, unsigned int *num_planes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
sizes[0] = GO7007_BUF_SIZE;
|
||||
*num_planes = 1;
|
||||
|
@@ -1624,7 +1624,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
static void sd_stopN(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
|
||||
|
||||
command_pause(gspca_dev);
|
||||
|
||||
|
@@ -522,7 +522,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
|
||||
frame = &gspca_dev->frame[i];
|
||||
frame->v4l2_buf.index = i;
|
||||
frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
frame->v4l2_buf.flags = 0;
|
||||
frame->v4l2_buf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
|
||||
frame->v4l2_buf.field = V4L2_FIELD_NONE;
|
||||
frame->v4l2_buf.length = frsz;
|
||||
frame->v4l2_buf.memory = memory;
|
||||
@@ -705,7 +705,7 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
|
||||
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
|
||||
bandwidth = psize * 1000;
|
||||
if (gspca_dev->dev->speed == USB_SPEED_HIGH
|
||||
|| gspca_dev->dev->speed == USB_SPEED_SUPER)
|
||||
|| gspca_dev->dev->speed >= USB_SPEED_SUPER)
|
||||
bandwidth *= 8;
|
||||
bandwidth /= 1 << (ep->desc.bInterval - 1);
|
||||
if (bandwidth <= last_bw)
|
||||
@@ -996,6 +996,19 @@ static int wxh_to_mode(struct gspca_dev *gspca_dev,
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < gspca_dev->cam.nmodes; i++) {
|
||||
if (width == gspca_dev->cam.cam_mode[i].width
|
||||
&& height == gspca_dev->cam.cam_mode[i].height)
|
||||
return i;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int wxh_to_nearest_mode(struct gspca_dev *gspca_dev,
|
||||
int width, int height)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = gspca_dev->cam.nmodes; --i > 0; ) {
|
||||
if (width >= gspca_dev->cam.cam_mode[i].width
|
||||
&& height >= gspca_dev->cam.cam_mode[i].height)
|
||||
@@ -1125,8 +1138,8 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev,
|
||||
PDEBUG_MODE(gspca_dev, D_CONF, "try fmt cap",
|
||||
fmt->fmt.pix.pixelformat, w, h);
|
||||
|
||||
/* search the closest mode for width and height */
|
||||
mode = wxh_to_mode(gspca_dev, w, h);
|
||||
/* search the nearest mode for width and height */
|
||||
mode = wxh_to_nearest_mode(gspca_dev, w, h);
|
||||
|
||||
/* OK if right palette */
|
||||
if (gspca_dev->cam.cam_mode[mode].pixelformat
|
||||
@@ -1233,9 +1246,13 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
|
||||
struct v4l2_frmivalenum *fival)
|
||||
{
|
||||
struct gspca_dev *gspca_dev = video_drvdata(filp);
|
||||
int mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
|
||||
int mode;
|
||||
__u32 i;
|
||||
|
||||
mode = wxh_to_mode(gspca_dev, fival->width, fival->height);
|
||||
if (mode < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (gspca_dev->cam.mode_framerates == NULL ||
|
||||
gspca_dev->cam.mode_framerates[mode].nrates == 0)
|
||||
return -EINVAL;
|
||||
@@ -1246,7 +1263,7 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
|
||||
|
||||
for (i = 0; i < gspca_dev->cam.mode_framerates[mode].nrates; i++) {
|
||||
if (fival->index == i) {
|
||||
fival->type = V4L2_FRMSIZE_TYPE_DISCRETE;
|
||||
fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
|
||||
fival->discrete.numerator = 1;
|
||||
fival->discrete.denominator =
|
||||
gspca_dev->cam.mode_framerates[mode].rates[i];
|
||||
|
@@ -243,7 +243,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
|
||||
static void sd_stopN(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
|
||||
|
||||
konica_stream_off(gspca_dev);
|
||||
#if IS_ENABLED(CONFIG_INPUT)
|
||||
|
@@ -115,21 +115,6 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* A skeleton used for sending messages to the m5602 bridge */
|
||||
static const unsigned char bridge_urb_skeleton[] = {
|
||||
0x13, 0x00, 0x81, 0x00
|
||||
};
|
||||
|
||||
/* A skeleton used for sending messages to the sensor */
|
||||
static const unsigned char sensor_urb_skeleton[] = {
|
||||
0x23, M5602_XB_GPIO_EN_H, 0x81, 0x06,
|
||||
0x23, M5602_XB_MISC_CTRL, 0x81, 0x80,
|
||||
0x13, M5602_XB_I2C_DEV_ADDR, 0x81, 0x00,
|
||||
0x13, M5602_XB_I2C_REG_ADDR, 0x81, 0x00,
|
||||
0x13, M5602_XB_I2C_DATA, 0x81, 0x00,
|
||||
0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
|
||||
};
|
||||
|
||||
struct sd {
|
||||
struct gspca_dev gspca_dev;
|
||||
|
||||
|
@@ -37,6 +37,21 @@ static const struct usb_device_id m5602_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, m5602_table);
|
||||
|
||||
/* A skeleton used for sending messages to the sensor */
|
||||
static const unsigned char sensor_urb_skeleton[] = {
|
||||
0x23, M5602_XB_GPIO_EN_H, 0x81, 0x06,
|
||||
0x23, M5602_XB_MISC_CTRL, 0x81, 0x80,
|
||||
0x13, M5602_XB_I2C_DEV_ADDR, 0x81, 0x00,
|
||||
0x13, M5602_XB_I2C_REG_ADDR, 0x81, 0x00,
|
||||
0x13, M5602_XB_I2C_DATA, 0x81, 0x00,
|
||||
0x13, M5602_XB_I2C_CTRL, 0x81, 0x11
|
||||
};
|
||||
|
||||
/* A skeleton used for sending messages to the m5602 bridge */
|
||||
static const unsigned char bridge_urb_skeleton[] = {
|
||||
0x13, 0x00, 0x81, 0x00
|
||||
};
|
||||
|
||||
/* Reads a byte from the m5602 */
|
||||
int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
|
||||
{
|
||||
|
@@ -23,6 +23,150 @@
|
||||
static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl);
|
||||
static void mt9m111_dump_registers(struct sd *sd);
|
||||
|
||||
static const unsigned char preinit_mt9m111[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_SC_RESET,
|
||||
MT9M111_RESET |
|
||||
MT9M111_RESTART |
|
||||
MT9M111_ANALOG_STANDBY |
|
||||
MT9M111_CHIP_DISABLE,
|
||||
MT9M111_SHOW_BAD_FRAMES |
|
||||
MT9M111_RESTART_BAD_FRAMES |
|
||||
MT9M111_SYNCHRONIZE_CHANGES},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_mt9m111[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
|
||||
|
||||
{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
|
||||
{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
|
||||
MT9M111_CP_OPERATING_MODE_CTL},
|
||||
{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
|
||||
{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
|
||||
MT9M111_2D_DEFECT_CORRECTION_ENABLE},
|
||||
{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
|
||||
MT9M111_2D_DEFECT_CORRECTION_ENABLE},
|
||||
{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
|
||||
{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
|
||||
{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
|
||||
{SENSOR, 0xcd, 0x00, 0x0e},
|
||||
{SENSOR, 0xd0, 0x00, 0x40},
|
||||
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
|
||||
{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
|
||||
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, 0x33, 0x03, 0x49},
|
||||
{SENSOR, 0x34, 0xc0, 0x19},
|
||||
{SENSOR, 0x3f, 0x20, 0x20},
|
||||
{SENSOR, 0x40, 0x20, 0x20},
|
||||
{SENSOR, 0x5a, 0xc0, 0x0a},
|
||||
{SENSOR, 0x70, 0x7b, 0x0a},
|
||||
{SENSOR, 0x71, 0xff, 0x00},
|
||||
{SENSOR, 0x72, 0x19, 0x0e},
|
||||
{SENSOR, 0x73, 0x18, 0x0f},
|
||||
{SENSOR, 0x74, 0x57, 0x32},
|
||||
{SENSOR, 0x75, 0x56, 0x34},
|
||||
{SENSOR, 0x76, 0x73, 0x35},
|
||||
{SENSOR, 0x77, 0x30, 0x12},
|
||||
{SENSOR, 0x78, 0x79, 0x02},
|
||||
{SENSOR, 0x79, 0x75, 0x06},
|
||||
{SENSOR, 0x7a, 0x77, 0x0a},
|
||||
{SENSOR, 0x7b, 0x78, 0x09},
|
||||
{SENSOR, 0x7c, 0x7d, 0x06},
|
||||
{SENSOR, 0x7d, 0x31, 0x10},
|
||||
{SENSOR, 0x7e, 0x00, 0x7e},
|
||||
{SENSOR, 0x80, 0x59, 0x04},
|
||||
{SENSOR, 0x81, 0x59, 0x04},
|
||||
{SENSOR, 0x82, 0x57, 0x0a},
|
||||
{SENSOR, 0x83, 0x58, 0x0b},
|
||||
{SENSOR, 0x84, 0x47, 0x0c},
|
||||
{SENSOR, 0x85, 0x48, 0x0e},
|
||||
{SENSOR, 0x86, 0x5b, 0x02},
|
||||
{SENSOR, 0x87, 0x00, 0x5c},
|
||||
{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
|
||||
{SENSOR, 0x60, 0x00, 0x80},
|
||||
{SENSOR, 0x61, 0x00, 0x00},
|
||||
{SENSOR, 0x62, 0x00, 0x00},
|
||||
{SENSOR, 0x63, 0x00, 0x00},
|
||||
{SENSOR, 0x64, 0x00, 0x00},
|
||||
|
||||
{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
|
||||
{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
|
||||
{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
|
||||
{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
|
||||
{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
|
||||
{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
|
||||
{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
|
||||
{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
|
||||
{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
|
||||
{SENSOR, 0x30, 0x04, 0x00},
|
||||
/* Set number of blank rows chosen to 400 */
|
||||
{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
|
||||
};
|
||||
|
||||
static const unsigned char start_mt9m111[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
};
|
||||
|
||||
static struct v4l2_pix_format mt9m111_modes[] = {
|
||||
{
|
||||
640,
|
||||
|
@@ -126,148 +126,4 @@ static const struct m5602_sensor mt9m111 = {
|
||||
.disconnect = mt9m111_disconnect,
|
||||
.start = mt9m111_start,
|
||||
};
|
||||
|
||||
static const unsigned char preinit_mt9m111[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_SC_RESET,
|
||||
MT9M111_RESET |
|
||||
MT9M111_RESTART |
|
||||
MT9M111_ANALOG_STANDBY |
|
||||
MT9M111_CHIP_DISABLE,
|
||||
MT9M111_SHOW_BAD_FRAMES |
|
||||
MT9M111_RESTART_BAD_FRAMES |
|
||||
MT9M111_SYNCHRONIZE_CHANGES},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3e, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_mt9m111[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3e, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x07, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x0b, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a, 0x00},
|
||||
|
||||
{SENSOR, MT9M111_SC_RESET, 0x00, 0x29},
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_SC_RESET, 0x00, 0x08},
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x01},
|
||||
{SENSOR, MT9M111_CP_OPERATING_MODE_CTL, 0x00,
|
||||
MT9M111_CP_OPERATING_MODE_CTL},
|
||||
{SENSOR, MT9M111_CP_LENS_CORRECTION_1, 0x04, 0x2a},
|
||||
{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_A, 0x00,
|
||||
MT9M111_2D_DEFECT_CORRECTION_ENABLE},
|
||||
{SENSOR, MT9M111_CP_DEFECT_CORR_CONTEXT_B, 0x00,
|
||||
MT9M111_2D_DEFECT_CORRECTION_ENABLE},
|
||||
{SENSOR, MT9M111_CP_LUMA_OFFSET, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_CP_LUMA_CLIP, 0xff, 0x00},
|
||||
{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_A, 0x14, 0x00},
|
||||
{SENSOR, MT9M111_CP_OUTPUT_FORMAT_CTL2_CONTEXT_B, 0x14, 0x00},
|
||||
{SENSOR, 0xcd, 0x00, 0x0e},
|
||||
{SENSOR, 0xd0, 0x00, 0x40},
|
||||
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x02},
|
||||
{SENSOR, MT9M111_CC_AUTO_EXPOSURE_PARAMETER_18, 0x00, 0x00},
|
||||
{SENSOR, MT9M111_CC_AWB_PARAMETER_7, 0xef, 0x03},
|
||||
|
||||
{SENSOR, MT9M111_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, 0x33, 0x03, 0x49},
|
||||
{SENSOR, 0x34, 0xc0, 0x19},
|
||||
{SENSOR, 0x3f, 0x20, 0x20},
|
||||
{SENSOR, 0x40, 0x20, 0x20},
|
||||
{SENSOR, 0x5a, 0xc0, 0x0a},
|
||||
{SENSOR, 0x70, 0x7b, 0x0a},
|
||||
{SENSOR, 0x71, 0xff, 0x00},
|
||||
{SENSOR, 0x72, 0x19, 0x0e},
|
||||
{SENSOR, 0x73, 0x18, 0x0f},
|
||||
{SENSOR, 0x74, 0x57, 0x32},
|
||||
{SENSOR, 0x75, 0x56, 0x34},
|
||||
{SENSOR, 0x76, 0x73, 0x35},
|
||||
{SENSOR, 0x77, 0x30, 0x12},
|
||||
{SENSOR, 0x78, 0x79, 0x02},
|
||||
{SENSOR, 0x79, 0x75, 0x06},
|
||||
{SENSOR, 0x7a, 0x77, 0x0a},
|
||||
{SENSOR, 0x7b, 0x78, 0x09},
|
||||
{SENSOR, 0x7c, 0x7d, 0x06},
|
||||
{SENSOR, 0x7d, 0x31, 0x10},
|
||||
{SENSOR, 0x7e, 0x00, 0x7e},
|
||||
{SENSOR, 0x80, 0x59, 0x04},
|
||||
{SENSOR, 0x81, 0x59, 0x04},
|
||||
{SENSOR, 0x82, 0x57, 0x0a},
|
||||
{SENSOR, 0x83, 0x58, 0x0b},
|
||||
{SENSOR, 0x84, 0x47, 0x0c},
|
||||
{SENSOR, 0x85, 0x48, 0x0e},
|
||||
{SENSOR, 0x86, 0x5b, 0x02},
|
||||
{SENSOR, 0x87, 0x00, 0x5c},
|
||||
{SENSOR, MT9M111_CONTEXT_CONTROL, 0x00, MT9M111_SEL_CONTEXT_B},
|
||||
{SENSOR, 0x60, 0x00, 0x80},
|
||||
{SENSOR, 0x61, 0x00, 0x00},
|
||||
{SENSOR, 0x62, 0x00, 0x00},
|
||||
{SENSOR, 0x63, 0x00, 0x00},
|
||||
{SENSOR, 0x64, 0x00, 0x00},
|
||||
|
||||
{SENSOR, MT9M111_SC_ROWSTART, 0x00, 0x0d}, /* 13 */
|
||||
{SENSOR, MT9M111_SC_COLSTART, 0x00, 0x12}, /* 18 */
|
||||
{SENSOR, MT9M111_SC_WINDOW_HEIGHT, 0x04, 0x00}, /* 1024 */
|
||||
{SENSOR, MT9M111_SC_WINDOW_WIDTH, 0x05, 0x10}, /* 1296 */
|
||||
{SENSOR, MT9M111_SC_HBLANK_CONTEXT_B, 0x01, 0x60}, /* 352 */
|
||||
{SENSOR, MT9M111_SC_VBLANK_CONTEXT_B, 0x00, 0x11}, /* 17 */
|
||||
{SENSOR, MT9M111_SC_HBLANK_CONTEXT_A, 0x01, 0x60}, /* 352 */
|
||||
{SENSOR, MT9M111_SC_VBLANK_CONTEXT_A, 0x00, 0x11}, /* 17 */
|
||||
{SENSOR, MT9M111_SC_R_MODE_CONTEXT_A, 0x01, 0x0f}, /* 271 */
|
||||
{SENSOR, 0x30, 0x04, 0x00},
|
||||
/* Set number of blank rows chosen to 400 */
|
||||
{SENSOR, MT9M111_SC_SHUTTER_WIDTH, 0x01, 0x90},
|
||||
};
|
||||
|
||||
static const unsigned char start_mt9m111[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
};
|
||||
#endif
|
||||
|
@@ -23,6 +23,159 @@
|
||||
static int ov7660_s_ctrl(struct v4l2_ctrl *ctrl);
|
||||
static void ov7660_dump_registers(struct sd *sd);
|
||||
|
||||
static const unsigned char preinit_ov7660[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
|
||||
{SENSOR, OV7660_OFON, 0x0c},
|
||||
{SENSOR, OV7660_COM2, 0x11},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_ov7660[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
{SENSOR, OV7660_COM7, 0x80},
|
||||
{SENSOR, OV7660_CLKRC, 0x80},
|
||||
{SENSOR, OV7660_COM9, 0x4c},
|
||||
{SENSOR, OV7660_OFON, 0x43},
|
||||
{SENSOR, OV7660_COM12, 0x28},
|
||||
{SENSOR, OV7660_COM8, 0x00},
|
||||
{SENSOR, OV7660_COM10, 0x40},
|
||||
{SENSOR, OV7660_HSTART, 0x0c},
|
||||
{SENSOR, OV7660_HSTOP, 0x61},
|
||||
{SENSOR, OV7660_HREF, 0xa4},
|
||||
{SENSOR, OV7660_PSHFT, 0x0b},
|
||||
{SENSOR, OV7660_VSTART, 0x01},
|
||||
{SENSOR, OV7660_VSTOP, 0x7a},
|
||||
{SENSOR, OV7660_VSTOP, 0x00},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
{SENSOR, OV7660_COM6, 0x42},
|
||||
{SENSOR, OV7660_BBIAS, 0x94},
|
||||
{SENSOR, OV7660_GbBIAS, 0x94},
|
||||
{SENSOR, OV7660_RSVD29, 0x94},
|
||||
{SENSOR, OV7660_RBIAS, 0x94},
|
||||
{SENSOR, OV7660_COM1, 0x00},
|
||||
{SENSOR, OV7660_AECH, 0x00},
|
||||
{SENSOR, OV7660_AECHH, 0x00},
|
||||
{SENSOR, OV7660_ADC, 0x05},
|
||||
{SENSOR, OV7660_COM13, 0x00},
|
||||
{SENSOR, OV7660_RSVDA1, 0x23},
|
||||
{SENSOR, OV7660_TSLB, 0x0d},
|
||||
{SENSOR, OV7660_HV, 0x80},
|
||||
{SENSOR, OV7660_LCC1, 0x00},
|
||||
{SENSOR, OV7660_LCC2, 0x00},
|
||||
{SENSOR, OV7660_LCC3, 0x10},
|
||||
{SENSOR, OV7660_LCC4, 0x40},
|
||||
{SENSOR, OV7660_LCC5, 0x01},
|
||||
|
||||
{SENSOR, OV7660_AECH, 0x20},
|
||||
{SENSOR, OV7660_COM1, 0x00},
|
||||
{SENSOR, OV7660_OFON, 0x0c},
|
||||
{SENSOR, OV7660_COM2, 0x11},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
{SENSOR, OV7660_AECH, 0x5f},
|
||||
{SENSOR, OV7660_COM1, 0x03},
|
||||
{SENSOR, OV7660_OFON, 0x0c},
|
||||
{SENSOR, OV7660_COM2, 0x11},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
};
|
||||
|
||||
static struct v4l2_pix_format ov7660_modes[] = {
|
||||
{
|
||||
640,
|
||||
|
@@ -107,157 +107,4 @@ static const struct m5602_sensor ov7660 = {
|
||||
.stop = ov7660_stop,
|
||||
.disconnect = ov7660_disconnect,
|
||||
};
|
||||
|
||||
static const unsigned char preinit_ov7660[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x03},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
|
||||
{SENSOR, OV7660_OFON, 0x0c},
|
||||
{SENSOR, OV7660_COM2, 0x11},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_ov7660[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
{SENSOR, OV7660_COM7, 0x80},
|
||||
{SENSOR, OV7660_CLKRC, 0x80},
|
||||
{SENSOR, OV7660_COM9, 0x4c},
|
||||
{SENSOR, OV7660_OFON, 0x43},
|
||||
{SENSOR, OV7660_COM12, 0x28},
|
||||
{SENSOR, OV7660_COM8, 0x00},
|
||||
{SENSOR, OV7660_COM10, 0x40},
|
||||
{SENSOR, OV7660_HSTART, 0x0c},
|
||||
{SENSOR, OV7660_HSTOP, 0x61},
|
||||
{SENSOR, OV7660_HREF, 0xa4},
|
||||
{SENSOR, OV7660_PSHFT, 0x0b},
|
||||
{SENSOR, OV7660_VSTART, 0x01},
|
||||
{SENSOR, OV7660_VSTOP, 0x7a},
|
||||
{SENSOR, OV7660_VSTOP, 0x00},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
{SENSOR, OV7660_COM6, 0x42},
|
||||
{SENSOR, OV7660_BBIAS, 0x94},
|
||||
{SENSOR, OV7660_GbBIAS, 0x94},
|
||||
{SENSOR, OV7660_RSVD29, 0x94},
|
||||
{SENSOR, OV7660_RBIAS, 0x94},
|
||||
{SENSOR, OV7660_COM1, 0x00},
|
||||
{SENSOR, OV7660_AECH, 0x00},
|
||||
{SENSOR, OV7660_AECHH, 0x00},
|
||||
{SENSOR, OV7660_ADC, 0x05},
|
||||
{SENSOR, OV7660_COM13, 0x00},
|
||||
{SENSOR, OV7660_RSVDA1, 0x23},
|
||||
{SENSOR, OV7660_TSLB, 0x0d},
|
||||
{SENSOR, OV7660_HV, 0x80},
|
||||
{SENSOR, OV7660_LCC1, 0x00},
|
||||
{SENSOR, OV7660_LCC2, 0x00},
|
||||
{SENSOR, OV7660_LCC3, 0x10},
|
||||
{SENSOR, OV7660_LCC4, 0x40},
|
||||
{SENSOR, OV7660_LCC5, 0x01},
|
||||
|
||||
{SENSOR, OV7660_AECH, 0x20},
|
||||
{SENSOR, OV7660_COM1, 0x00},
|
||||
{SENSOR, OV7660_OFON, 0x0c},
|
||||
{SENSOR, OV7660_COM2, 0x11},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
{SENSOR, OV7660_AECH, 0x5f},
|
||||
{SENSOR, OV7660_COM1, 0x03},
|
||||
{SENSOR, OV7660_OFON, 0x0c},
|
||||
{SENSOR, OV7660_COM2, 0x11},
|
||||
{SENSOR, OV7660_COM7, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x01},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x08},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
};
|
||||
#endif
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Driver for the ov9650 sensor
|
||||
*
|
||||
@@ -23,6 +24,157 @@
|
||||
static int ov9650_s_ctrl(struct v4l2_ctrl *ctrl);
|
||||
static void ov9650_dump_registers(struct sd *sd);
|
||||
|
||||
static const unsigned char preinit_ov9650[][3] = {
|
||||
/* [INITCAM] */
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
|
||||
/* Reset chip */
|
||||
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
|
||||
/* Enable double clock */
|
||||
{SENSOR, OV9650_CLKRC, 0x80},
|
||||
/* Do something out of spec with the power */
|
||||
{SENSOR, OV9650_OFON, 0x40}
|
||||
};
|
||||
|
||||
static const unsigned char init_ov9650[][3] = {
|
||||
/* [INITCAM] */
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
|
||||
|
||||
/* Reset chip */
|
||||
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
|
||||
/* One extra reset is needed in order to make the sensor behave
|
||||
properly when resuming from ram, could be a timing issue */
|
||||
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
|
||||
|
||||
/* Enable double clock */
|
||||
{SENSOR, OV9650_CLKRC, 0x80},
|
||||
/* Do something out of spec with the power */
|
||||
{SENSOR, OV9650_OFON, 0x40},
|
||||
|
||||
/* Set fast AGC/AEC algorithm with unlimited step size */
|
||||
{SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
|
||||
OV9650_AEC_UNLIM_STEP_SIZE},
|
||||
|
||||
{SENSOR, OV9650_CHLF, 0x10},
|
||||
{SENSOR, OV9650_ARBLM, 0xbf},
|
||||
{SENSOR, OV9650_ACOM38, 0x81},
|
||||
/* Turn off color matrix coefficient double option */
|
||||
{SENSOR, OV9650_COM16, 0x00},
|
||||
/* Enable color matrix for RGB/YUV, Delay Y channel,
|
||||
set output Y/UV delay to 1 */
|
||||
{SENSOR, OV9650_COM13, 0x19},
|
||||
/* Enable digital BLC, Set output mode to U Y V Y */
|
||||
{SENSOR, OV9650_TSLB, 0x0c},
|
||||
/* Limit the AGC/AEC stable upper region */
|
||||
{SENSOR, OV9650_COM24, 0x00},
|
||||
/* Enable HREF and some out of spec things */
|
||||
{SENSOR, OV9650_COM12, 0x73},
|
||||
/* Set all DBLC offset signs to positive and
|
||||
do some out of spec stuff */
|
||||
{SENSOR, OV9650_DBLC1, 0xdf},
|
||||
{SENSOR, OV9650_COM21, 0x06},
|
||||
{SENSOR, OV9650_RSVD35, 0x91},
|
||||
/* Necessary, no camera stream without it */
|
||||
{SENSOR, OV9650_RSVD16, 0x06},
|
||||
{SENSOR, OV9650_RSVD94, 0x99},
|
||||
{SENSOR, OV9650_RSVD95, 0x99},
|
||||
{SENSOR, OV9650_RSVD96, 0x04},
|
||||
/* Enable full range output */
|
||||
{SENSOR, OV9650_COM15, 0x0},
|
||||
/* Enable HREF at optical black, enable ADBLC bias,
|
||||
enable ADBLC, reset timings at format change */
|
||||
{SENSOR, OV9650_COM6, 0x4b},
|
||||
/* Subtract 32 from the B channel bias */
|
||||
{SENSOR, OV9650_BBIAS, 0xa0},
|
||||
/* Subtract 32 from the Gb channel bias */
|
||||
{SENSOR, OV9650_GbBIAS, 0xa0},
|
||||
/* Do not bypass the analog BLC and to some out of spec stuff */
|
||||
{SENSOR, OV9650_Gr_COM, 0x00},
|
||||
/* Subtract 32 from the R channel bias */
|
||||
{SENSOR, OV9650_RBIAS, 0xa0},
|
||||
/* Subtract 32 from the R channel bias */
|
||||
{SENSOR, OV9650_RBIAS, 0x0},
|
||||
{SENSOR, OV9650_COM26, 0x80},
|
||||
{SENSOR, OV9650_ACOMA9, 0x98},
|
||||
/* Set the AGC/AEC stable region upper limit */
|
||||
{SENSOR, OV9650_AEW, 0x68},
|
||||
/* Set the AGC/AEC stable region lower limit */
|
||||
{SENSOR, OV9650_AEB, 0x5c},
|
||||
/* Set the high and low limit nibbles to 3 */
|
||||
{SENSOR, OV9650_VPT, 0xc3},
|
||||
/* Set the Automatic Gain Ceiling (AGC) to 128x,
|
||||
drop VSYNC at frame drop,
|
||||
limit exposure timing,
|
||||
drop frame when the AEC step is larger than the exposure gap */
|
||||
{SENSOR, OV9650_COM9, 0x6e},
|
||||
/* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
|
||||
and set PWDN to SLVS (slave mode vertical sync) */
|
||||
{SENSOR, OV9650_COM10, 0x42},
|
||||
/* Set horizontal column start high to default value */
|
||||
{SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
|
||||
/* Set horizontal column end */
|
||||
{SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
|
||||
/* Complementing register to the two writes above */
|
||||
{SENSOR, OV9650_HREF, 0xb2},
|
||||
/* Set vertical row start high bits */
|
||||
{SENSOR, OV9650_VSTRT, 0x02},
|
||||
/* Set vertical row end low bits */
|
||||
{SENSOR, OV9650_VSTOP, 0x7e},
|
||||
/* Set complementing vertical frame control */
|
||||
{SENSOR, OV9650_VREF, 0x10},
|
||||
{SENSOR, OV9650_ADC, 0x04},
|
||||
{SENSOR, OV9650_HV, 0x40},
|
||||
|
||||
/* Enable denoise, and white-pixel erase */
|
||||
{SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
|
||||
OV9650_WHITE_PIXEL_ENABLE |
|
||||
OV9650_WHITE_PIXEL_OPTION},
|
||||
|
||||
/* Enable VARIOPIXEL */
|
||||
{SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
|
||||
{SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
|
||||
|
||||
/* Put the sensor in soft sleep mode */
|
||||
{SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
|
||||
};
|
||||
|
||||
static const unsigned char res_init_ov9650[][3] = {
|
||||
{SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
|
||||
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01}
|
||||
};
|
||||
|
||||
/* Vertically and horizontally flips the image if matched, needed for machines
|
||||
where the sensor is mounted upside down */
|
||||
static
|
||||
|
@@ -156,154 +156,4 @@ static const struct m5602_sensor ov9650 = {
|
||||
.disconnect = ov9650_disconnect,
|
||||
};
|
||||
|
||||
static const unsigned char preinit_ov9650[][3] = {
|
||||
/* [INITCAM] */
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
|
||||
/* Reset chip */
|
||||
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
|
||||
/* Enable double clock */
|
||||
{SENSOR, OV9650_CLKRC, 0x80},
|
||||
/* Do something out of spec with the power */
|
||||
{SENSOR, OV9650_OFON, 0x40}
|
||||
};
|
||||
|
||||
static const unsigned char init_ov9650[][3] = {
|
||||
/* [INITCAM] */
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x0a},
|
||||
|
||||
/* Reset chip */
|
||||
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
|
||||
/* One extra reset is needed in order to make the sensor behave
|
||||
properly when resuming from ram, could be a timing issue */
|
||||
{SENSOR, OV9650_COM7, OV9650_REGISTER_RESET},
|
||||
|
||||
/* Enable double clock */
|
||||
{SENSOR, OV9650_CLKRC, 0x80},
|
||||
/* Do something out of spec with the power */
|
||||
{SENSOR, OV9650_OFON, 0x40},
|
||||
|
||||
/* Set fast AGC/AEC algorithm with unlimited step size */
|
||||
{SENSOR, OV9650_COM8, OV9650_FAST_AGC_AEC |
|
||||
OV9650_AEC_UNLIM_STEP_SIZE},
|
||||
|
||||
{SENSOR, OV9650_CHLF, 0x10},
|
||||
{SENSOR, OV9650_ARBLM, 0xbf},
|
||||
{SENSOR, OV9650_ACOM38, 0x81},
|
||||
/* Turn off color matrix coefficient double option */
|
||||
{SENSOR, OV9650_COM16, 0x00},
|
||||
/* Enable color matrix for RGB/YUV, Delay Y channel,
|
||||
set output Y/UV delay to 1 */
|
||||
{SENSOR, OV9650_COM13, 0x19},
|
||||
/* Enable digital BLC, Set output mode to U Y V Y */
|
||||
{SENSOR, OV9650_TSLB, 0x0c},
|
||||
/* Limit the AGC/AEC stable upper region */
|
||||
{SENSOR, OV9650_COM24, 0x00},
|
||||
/* Enable HREF and some out of spec things */
|
||||
{SENSOR, OV9650_COM12, 0x73},
|
||||
/* Set all DBLC offset signs to positive and
|
||||
do some out of spec stuff */
|
||||
{SENSOR, OV9650_DBLC1, 0xdf},
|
||||
{SENSOR, OV9650_COM21, 0x06},
|
||||
{SENSOR, OV9650_RSVD35, 0x91},
|
||||
/* Necessary, no camera stream without it */
|
||||
{SENSOR, OV9650_RSVD16, 0x06},
|
||||
{SENSOR, OV9650_RSVD94, 0x99},
|
||||
{SENSOR, OV9650_RSVD95, 0x99},
|
||||
{SENSOR, OV9650_RSVD96, 0x04},
|
||||
/* Enable full range output */
|
||||
{SENSOR, OV9650_COM15, 0x0},
|
||||
/* Enable HREF at optical black, enable ADBLC bias,
|
||||
enable ADBLC, reset timings at format change */
|
||||
{SENSOR, OV9650_COM6, 0x4b},
|
||||
/* Subtract 32 from the B channel bias */
|
||||
{SENSOR, OV9650_BBIAS, 0xa0},
|
||||
/* Subtract 32 from the Gb channel bias */
|
||||
{SENSOR, OV9650_GbBIAS, 0xa0},
|
||||
/* Do not bypass the analog BLC and to some out of spec stuff */
|
||||
{SENSOR, OV9650_Gr_COM, 0x00},
|
||||
/* Subtract 32 from the R channel bias */
|
||||
{SENSOR, OV9650_RBIAS, 0xa0},
|
||||
/* Subtract 32 from the R channel bias */
|
||||
{SENSOR, OV9650_RBIAS, 0x0},
|
||||
{SENSOR, OV9650_COM26, 0x80},
|
||||
{SENSOR, OV9650_ACOMA9, 0x98},
|
||||
/* Set the AGC/AEC stable region upper limit */
|
||||
{SENSOR, OV9650_AEW, 0x68},
|
||||
/* Set the AGC/AEC stable region lower limit */
|
||||
{SENSOR, OV9650_AEB, 0x5c},
|
||||
/* Set the high and low limit nibbles to 3 */
|
||||
{SENSOR, OV9650_VPT, 0xc3},
|
||||
/* Set the Automatic Gain Ceiling (AGC) to 128x,
|
||||
drop VSYNC at frame drop,
|
||||
limit exposure timing,
|
||||
drop frame when the AEC step is larger than the exposure gap */
|
||||
{SENSOR, OV9650_COM9, 0x6e},
|
||||
/* Set VSYNC negative, Set RESET to SLHS (slave mode horizontal sync)
|
||||
and set PWDN to SLVS (slave mode vertical sync) */
|
||||
{SENSOR, OV9650_COM10, 0x42},
|
||||
/* Set horizontal column start high to default value */
|
||||
{SENSOR, OV9650_HSTART, 0x1a}, /* 210 */
|
||||
/* Set horizontal column end */
|
||||
{SENSOR, OV9650_HSTOP, 0xbf}, /* 1534 */
|
||||
/* Complementing register to the two writes above */
|
||||
{SENSOR, OV9650_HREF, 0xb2},
|
||||
/* Set vertical row start high bits */
|
||||
{SENSOR, OV9650_VSTRT, 0x02},
|
||||
/* Set vertical row end low bits */
|
||||
{SENSOR, OV9650_VSTOP, 0x7e},
|
||||
/* Set complementing vertical frame control */
|
||||
{SENSOR, OV9650_VREF, 0x10},
|
||||
{SENSOR, OV9650_ADC, 0x04},
|
||||
{SENSOR, OV9650_HV, 0x40},
|
||||
|
||||
/* Enable denoise, and white-pixel erase */
|
||||
{SENSOR, OV9650_COM22, OV9650_DENOISE_ENABLE |
|
||||
OV9650_WHITE_PIXEL_ENABLE |
|
||||
OV9650_WHITE_PIXEL_OPTION},
|
||||
|
||||
/* Enable VARIOPIXEL */
|
||||
{SENSOR, OV9650_COM3, OV9650_VARIOPIXEL},
|
||||
{SENSOR, OV9650_COM4, OV9650_QVGA_VARIOPIXEL},
|
||||
|
||||
/* Put the sensor in soft sleep mode */
|
||||
{SENSOR, OV9650_COM2, OV9650_SOFT_SLEEP | OV9650_OUTPUT_DRIVE_2X},
|
||||
};
|
||||
|
||||
static const unsigned char res_init_ov9650[][3] = {
|
||||
{SENSOR, OV9650_COM2, OV9650_OUTPUT_DRIVE_2X},
|
||||
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x82},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_L, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_L, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01}
|
||||
};
|
||||
#endif
|
||||
|
@@ -23,6 +23,110 @@
|
||||
static int po1030_s_ctrl(struct v4l2_ctrl *ctrl);
|
||||
static void po1030_dump_registers(struct sd *sd);
|
||||
|
||||
static const unsigned char preinit_po1030[][3] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
|
||||
|
||||
{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
|
||||
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_po1030[][3] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
|
||||
{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
|
||||
{SENSOR, PO1030_AUTOCTRL2, 0x04},
|
||||
|
||||
{SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
|
||||
{SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
|
||||
|
||||
{SENSOR, PO1030_CONTROL2, 0x03},
|
||||
{SENSOR, 0x21, 0x90},
|
||||
{SENSOR, PO1030_YTARGET, 0x60},
|
||||
{SENSOR, 0x59, 0x13},
|
||||
{SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
|
||||
{SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
|
||||
{SENSOR, PO1030_EGA, 0x80},
|
||||
{SENSOR, 0x78, 0x14},
|
||||
{SENSOR, 0x6f, 0x01},
|
||||
{SENSOR, PO1030_GLOBALGAINMAX, 0x14},
|
||||
{SENSOR, PO1030_Cb_U_GAIN, 0x38},
|
||||
{SENSOR, PO1030_Cr_V_GAIN, 0x38},
|
||||
{SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
|
||||
PO1030_AUTO_SUBSAMPLING |
|
||||
PO1030_FRAME_EQUAL},
|
||||
{SENSOR, PO1030_GC0, 0x10},
|
||||
{SENSOR, PO1030_GC1, 0x20},
|
||||
{SENSOR, PO1030_GC2, 0x40},
|
||||
{SENSOR, PO1030_GC3, 0x60},
|
||||
{SENSOR, PO1030_GC4, 0x80},
|
||||
{SENSOR, PO1030_GC5, 0xa0},
|
||||
{SENSOR, PO1030_GC6, 0xc0},
|
||||
{SENSOR, PO1030_GC7, 0xff},
|
||||
|
||||
/* Set the width to 751 */
|
||||
{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
|
||||
{SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
|
||||
|
||||
/* Set the height to 540 */
|
||||
{SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
|
||||
{SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
|
||||
|
||||
/* Set the x window to 1 */
|
||||
{SENSOR, PO1030_WINDOWX_H, 0x00},
|
||||
{SENSOR, PO1030_WINDOWX_L, 0x01},
|
||||
|
||||
/* Set the y window to 1 */
|
||||
{SENSOR, PO1030_WINDOWY_H, 0x00},
|
||||
{SENSOR, PO1030_WINDOWY_L, 0x01},
|
||||
|
||||
/* with a very low lighted environment increase the exposure but
|
||||
* decrease the FPS (Frame Per Second) */
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
};
|
||||
|
||||
static struct v4l2_pix_format po1030_modes[] = {
|
||||
{
|
||||
640,
|
||||
|
@@ -167,108 +167,4 @@ static const struct m5602_sensor po1030 = {
|
||||
.start = po1030_start,
|
||||
.disconnect = po1030_disconnect,
|
||||
};
|
||||
|
||||
static const unsigned char preinit_po1030[][3] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
|
||||
|
||||
{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
|
||||
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_po1030[][3] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
|
||||
|
||||
{SENSOR, PO1030_AUTOCTRL2, PO1030_SENSOR_RESET | (1 << 2)},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x04},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x02},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x04},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
|
||||
{SENSOR, PO1030_AUTOCTRL2, 0x04},
|
||||
|
||||
{SENSOR, PO1030_OUTFORMCTRL2, PO1030_RAW_RGB_BAYER},
|
||||
{SENSOR, PO1030_AUTOCTRL1, PO1030_WEIGHT_WIN_2X},
|
||||
|
||||
{SENSOR, PO1030_CONTROL2, 0x03},
|
||||
{SENSOR, 0x21, 0x90},
|
||||
{SENSOR, PO1030_YTARGET, 0x60},
|
||||
{SENSOR, 0x59, 0x13},
|
||||
{SENSOR, PO1030_OUTFORMCTRL1, PO1030_HREF_ENABLE},
|
||||
{SENSOR, PO1030_EDGE_ENH_OFF, 0x00},
|
||||
{SENSOR, PO1030_EGA, 0x80},
|
||||
{SENSOR, 0x78, 0x14},
|
||||
{SENSOR, 0x6f, 0x01},
|
||||
{SENSOR, PO1030_GLOBALGAINMAX, 0x14},
|
||||
{SENSOR, PO1030_Cb_U_GAIN, 0x38},
|
||||
{SENSOR, PO1030_Cr_V_GAIN, 0x38},
|
||||
{SENSOR, PO1030_CONTROL1, PO1030_SHUTTER_MODE |
|
||||
PO1030_AUTO_SUBSAMPLING |
|
||||
PO1030_FRAME_EQUAL},
|
||||
{SENSOR, PO1030_GC0, 0x10},
|
||||
{SENSOR, PO1030_GC1, 0x20},
|
||||
{SENSOR, PO1030_GC2, 0x40},
|
||||
{SENSOR, PO1030_GC3, 0x60},
|
||||
{SENSOR, PO1030_GC4, 0x80},
|
||||
{SENSOR, PO1030_GC5, 0xa0},
|
||||
{SENSOR, PO1030_GC6, 0xc0},
|
||||
{SENSOR, PO1030_GC7, 0xff},
|
||||
|
||||
/* Set the width to 751 */
|
||||
{SENSOR, PO1030_FRAMEWIDTH_H, 0x02},
|
||||
{SENSOR, PO1030_FRAMEWIDTH_L, 0xef},
|
||||
|
||||
/* Set the height to 540 */
|
||||
{SENSOR, PO1030_FRAMEHEIGHT_H, 0x02},
|
||||
{SENSOR, PO1030_FRAMEHEIGHT_L, 0x1c},
|
||||
|
||||
/* Set the x window to 1 */
|
||||
{SENSOR, PO1030_WINDOWX_H, 0x00},
|
||||
{SENSOR, PO1030_WINDOWX_L, 0x01},
|
||||
|
||||
/* Set the y window to 1 */
|
||||
{SENSOR, PO1030_WINDOWY_H, 0x00},
|
||||
{SENSOR, PO1030_WINDOWY_L, 0x01},
|
||||
|
||||
/* with a very low lighted environment increase the exposure but
|
||||
* decrease the FPS (Frame Per Second) */
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x05},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
|
||||
};
|
||||
#endif
|
||||
|
@@ -20,6 +20,205 @@
|
||||
|
||||
#include "m5602_s5k4aa.h"
|
||||
|
||||
static const unsigned char preinit_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x07, 0x00},
|
||||
{SENSOR, 0x36, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, 0x7b, 0xff, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, 0x0c, 0x05, 0x00},
|
||||
{SENSOR, 0x02, 0x0e, 0x00},
|
||||
{SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
|
||||
{SENSOR, 0x37, 0x00, 0x00},
|
||||
};
|
||||
|
||||
static const unsigned char VGA_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
/* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
/* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
|
||||
| S5K4AA_RM_COL_SKIP_2X, 0x00},
|
||||
/* 0x37 : Fix image stability when light is too bright and improves
|
||||
* image quality in 640x480, but worsens it in 1280x1024 */
|
||||
{SENSOR, 0x37, 0x01, 0x00},
|
||||
/* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
|
||||
{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
|
||||
/* window_height_hi, window_height_lo : 960 = 0x03c0 */
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
|
||||
/* window_width_hi, window_width_lo : 1280 = 0x0500 */
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
|
||||
{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
|
||||
{SENSOR, 0x11, 0x04, 0x00},
|
||||
{SENSOR, 0x12, 0xc3, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, 0x02, 0x0e, 0x00},
|
||||
};
|
||||
|
||||
static const unsigned char SXGA_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
/* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
/* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
|
||||
{SENSOR, 0x37, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
|
||||
{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
|
||||
{SENSOR, 0x11, 0x04, 0x00},
|
||||
{SENSOR, 0x12, 0xc3, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, 0x02, 0x0e, 0x00},
|
||||
};
|
||||
|
||||
|
||||
static int s5k4aa_s_ctrl(struct v4l2_ctrl *ctrl);
|
||||
static void s5k4aa_dump_registers(struct sd *sd);
|
||||
|
||||
|
@@ -85,201 +85,4 @@ static const struct m5602_sensor s5k4aa = {
|
||||
.disconnect = s5k4aa_disconnect,
|
||||
};
|
||||
|
||||
static const unsigned char preinit_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00}
|
||||
};
|
||||
|
||||
static const unsigned char init_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x14, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x07, 0x00},
|
||||
{SENSOR, 0x36, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, 0x7b, 0xff, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, 0x0c, 0x05, 0x00},
|
||||
{SENSOR, 0x02, 0x0e, 0x00},
|
||||
{SENSOR, S5K4AA_READ_MODE, 0xa0, 0x00},
|
||||
{SENSOR, 0x37, 0x00, 0x00},
|
||||
};
|
||||
|
||||
static const unsigned char VGA_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
/* VSYNC_PARA, VSYNC_PARA : img height 480 = 0x01e0 */
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0xe0, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
/* HSYNC_PARA, HSYNC_PARA : img width 640 = 0x0280 */
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP | S5K4AA_RM_ROW_SKIP_2X
|
||||
| S5K4AA_RM_COL_SKIP_2X, 0x00},
|
||||
/* 0x37 : Fix image stability when light is too bright and improves
|
||||
* image quality in 640x480, but worsens it in 1280x1024 */
|
||||
{SENSOR, 0x37, 0x01, 0x00},
|
||||
/* ROWSTART_HI, ROWSTART_LO : 10 + (1024-960)/2 = 42 = 0x002a */
|
||||
{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_ROWSTART_LO, 0x29, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_LO, 0x0c, 0x00},
|
||||
/* window_height_hi, window_height_lo : 960 = 0x03c0 */
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x03, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0xc0, 0x00},
|
||||
/* window_width_hi, window_width_lo : 1280 = 0x0500 */
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_HI__, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00}, /* helps to sync... */
|
||||
{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
|
||||
{SENSOR, 0x11, 0x04, 0x00},
|
||||
{SENSOR, 0x12, 0xc3, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, 0x02, 0x0e, 0x00},
|
||||
};
|
||||
|
||||
static const unsigned char SXGA_s5k4aa[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
/* VSYNC_PARA, VSYNC_PARA : img height 1024 = 0x0400 */
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x04, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
/* HSYNC_PARA, HSYNC_PARA : img width 1280 = 0x0500 */
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x05, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xa0, 0x00}, /* 48 MHz */
|
||||
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, S5K4AA_READ_MODE, S5K4AA_RM_H_FLIP, 0x00},
|
||||
{SENSOR, 0x37, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_ROWSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_ROWSTART_LO, 0x09, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_HI, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_COLSTART_LO, 0x0a, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_HI, 0x04, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_HEIGHT_LO, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_HI, 0x05, 0x00},
|
||||
{SENSOR, S5K4AA_WINDOW_WIDTH_LO, 0x00, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_HI__, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_H_BLANK_LO__, 0xa8, 0x00},
|
||||
{SENSOR, S5K4AA_EXPOSURE_HI, 0x01, 0x00},
|
||||
{SENSOR, S5K4AA_EXPOSURE_LO, 0x00, 0x00},
|
||||
{SENSOR, 0x11, 0x04, 0x00},
|
||||
{SENSOR, 0x12, 0xc3, 0x00},
|
||||
{SENSOR, S5K4AA_PAGE_MAP, 0x02, 0x00},
|
||||
{SENSOR, 0x02, 0x0e, 0x00},
|
||||
};
|
||||
#endif
|
||||
|
@@ -41,6 +41,130 @@ static struct v4l2_pix_format s5k83a_modes[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned char preinit_s5k83a[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
};
|
||||
|
||||
/* This could probably be considerably shortened.
|
||||
I don't have the hardware to experiment with it, patches welcome
|
||||
*/
|
||||
static const unsigned char init_s5k83a[][4] = {
|
||||
/* The following sequence is useless after a clean boot
|
||||
but is necessary after resume from suspend */
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
|
||||
{SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
|
||||
{SENSOR, 0xaf, 0x01, 0x00},
|
||||
{SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, 0x7b, 0xff, 0x00},
|
||||
{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
|
||||
{SENSOR, 0x01, 0x50, 0x00},
|
||||
{SENSOR, 0x12, 0x20, 0x00},
|
||||
{SENSOR, 0x17, 0x40, 0x00},
|
||||
{SENSOR, 0x1c, 0x00, 0x00},
|
||||
{SENSOR, 0x02, 0x70, 0x00},
|
||||
{SENSOR, 0x03, 0x0b, 0x00},
|
||||
{SENSOR, 0x04, 0xf0, 0x00},
|
||||
{SENSOR, 0x05, 0x0b, 0x00},
|
||||
{SENSOR, 0x06, 0x71, 0x00},
|
||||
{SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
|
||||
{SENSOR, 0x08, 0x02, 0x00},
|
||||
{SENSOR, 0x09, 0x88, 0x00}, /* 648 */
|
||||
{SENSOR, 0x14, 0x00, 0x00},
|
||||
{SENSOR, 0x15, 0x20, 0x00}, /* 32 */
|
||||
{SENSOR, 0x19, 0x00, 0x00},
|
||||
{SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
|
||||
{SENSOR, 0x0f, 0x02, 0x00},
|
||||
{SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
|
||||
/* normal colors
|
||||
(this is value after boot, but after tries can be different) */
|
||||
{SENSOR, 0x00, 0x06, 0x00},
|
||||
};
|
||||
|
||||
static const unsigned char start_s5k83a[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
};
|
||||
|
||||
static void s5k83a_dump_registers(struct sd *sd);
|
||||
static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data);
|
||||
static int s5k83a_set_led_indication(struct sd *sd, u8 val);
|
||||
|
@@ -61,128 +61,4 @@ static const struct m5602_sensor s5k83a = {
|
||||
.i2c_slave_id = 0x5a,
|
||||
.i2c_regW = 2,
|
||||
};
|
||||
|
||||
static const unsigned char preinit_s5k83a[][4] = {
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_CTRL, 0x00, 0x00},
|
||||
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x1c, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
};
|
||||
|
||||
/* This could probably be considerably shortened.
|
||||
I don't have the hardware to experiment with it, patches welcome
|
||||
*/
|
||||
static const unsigned char init_s5k83a[][4] = {
|
||||
/* The following sequence is useless after a clean boot
|
||||
but is necessary after resume from suspend */
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x3f, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_L, 0xff, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0x80, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_DIV, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_MCU_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xf0, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR, 0x1d, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT, 0x08, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DIR_H, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_DAT_H, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_GPIO_EN_L, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_I2C_CLK_DIV, 0x20, 0x00},
|
||||
|
||||
{SENSOR, S5K83A_PAGE_MAP, 0x04, 0x00},
|
||||
{SENSOR, 0xaf, 0x01, 0x00},
|
||||
{SENSOR, S5K83A_PAGE_MAP, 0x00, 0x00},
|
||||
{SENSOR, 0x7b, 0xff, 0x00},
|
||||
{SENSOR, S5K83A_PAGE_MAP, 0x05, 0x00},
|
||||
{SENSOR, 0x01, 0x50, 0x00},
|
||||
{SENSOR, 0x12, 0x20, 0x00},
|
||||
{SENSOR, 0x17, 0x40, 0x00},
|
||||
{SENSOR, 0x1c, 0x00, 0x00},
|
||||
{SENSOR, 0x02, 0x70, 0x00},
|
||||
{SENSOR, 0x03, 0x0b, 0x00},
|
||||
{SENSOR, 0x04, 0xf0, 0x00},
|
||||
{SENSOR, 0x05, 0x0b, 0x00},
|
||||
{SENSOR, 0x06, 0x71, 0x00},
|
||||
{SENSOR, 0x07, 0xe8, 0x00}, /* 488 */
|
||||
{SENSOR, 0x08, 0x02, 0x00},
|
||||
{SENSOR, 0x09, 0x88, 0x00}, /* 648 */
|
||||
{SENSOR, 0x14, 0x00, 0x00},
|
||||
{SENSOR, 0x15, 0x20, 0x00}, /* 32 */
|
||||
{SENSOR, 0x19, 0x00, 0x00},
|
||||
{SENSOR, 0x1a, 0x98, 0x00}, /* 152 */
|
||||
{SENSOR, 0x0f, 0x02, 0x00},
|
||||
{SENSOR, 0x10, 0xe5, 0x00}, /* 741 */
|
||||
/* normal colors
|
||||
(this is value after boot, but after tries can be different) */
|
||||
{SENSOR, 0x00, 0x06, 0x00},
|
||||
};
|
||||
|
||||
static const unsigned char start_s5k83a[][4] = {
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
{BRIDGE, M5602_XB_ADC_CTRL, 0xc0, 0x00},
|
||||
{BRIDGE, M5602_XB_SENSOR_TYPE, 0x09, 0x00},
|
||||
{BRIDGE, M5602_XB_LINE_OF_FRAME_H, 0x81, 0x00},
|
||||
{BRIDGE, M5602_XB_PIX_OF_LINE_H, 0x82, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x01, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0xe4, 0x00}, /* 484 */
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_VSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x02, 0x00},
|
||||
{BRIDGE, M5602_XB_HSYNC_PARA, 0x7f, 0x00}, /* 639 */
|
||||
{BRIDGE, M5602_XB_SIG_INI, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00, 0x00},
|
||||
{BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0, 0x00},
|
||||
};
|
||||
#endif
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#define OV534_OP_READ_2 0xf9
|
||||
|
||||
#define CTRL_TIMEOUT 500
|
||||
#define DEFAULT_FRAME_RATE 30
|
||||
|
||||
MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
|
||||
MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
|
||||
@@ -1061,7 +1062,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||
cam->cam_mode = ov772x_mode;
|
||||
cam->nmodes = ARRAY_SIZE(ov772x_mode);
|
||||
|
||||
sd->frame_rate = 30;
|
||||
sd->frame_rate = DEFAULT_FRAME_RATE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1492,10 +1493,8 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev,
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (tpf->numerator == 0 || tpf->denominator == 0)
|
||||
/* Set default framerate */
|
||||
sd->frame_rate = 30;
|
||||
sd->frame_rate = DEFAULT_FRAME_RATE;
|
||||
else
|
||||
/* Set requested framerate */
|
||||
sd->frame_rate = tpf->denominator / tpf->numerator;
|
||||
|
||||
if (gspca_dev->streaming)
|
||||
|
@@ -92,7 +92,6 @@ struct sd {
|
||||
struct v4l2_ctrl *jpegqual;
|
||||
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *work_thread;
|
||||
|
||||
u32 pktsz; /* (used by pkt_scan) */
|
||||
u16 npkt;
|
||||
@@ -2051,8 +2050,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
if (mode & MODE_JPEG) {
|
||||
sd->pktsz = sd->npkt = 0;
|
||||
sd->nchg = 0;
|
||||
sd->work_thread =
|
||||
create_singlethread_workqueue(KBUILD_MODNAME);
|
||||
}
|
||||
|
||||
return gspca_dev->usb_err;
|
||||
@@ -2070,12 +2067,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->work_thread != NULL) {
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
destroy_workqueue(sd->work_thread);
|
||||
mutex_lock(&gspca_dev->usb_lock);
|
||||
sd->work_thread = NULL;
|
||||
}
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
flush_work(&sd->work);
|
||||
mutex_lock(&gspca_dev->usb_lock);
|
||||
}
|
||||
|
||||
static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
|
||||
@@ -2228,7 +2222,7 @@ static void transfer_check(struct gspca_dev *gspca_dev,
|
||||
new_qual = sd->jpegqual->maximum;
|
||||
if (new_qual != curqual) {
|
||||
sd->jpegqual->cur.val = new_qual;
|
||||
queue_work(sd->work_thread, &sd->work);
|
||||
schedule_work(&sd->work);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@@ -837,7 +837,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
u8 *data, /* isoc packet */
|
||||
int len) /* iso packet length */
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
struct sd *sd __maybe_unused = (struct sd *) gspca_dev;
|
||||
int pkt_type;
|
||||
|
||||
if (data[0] == 0x5a) {
|
||||
|
@@ -175,6 +175,8 @@ static const u8 jpeg_q[17] = {
|
||||
#error "USB buffer too small"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_FRAME_RATE 30
|
||||
|
||||
static const u8 rates[] = {30, 20, 15, 10, 7, 5};
|
||||
static const struct framerates framerates[] = {
|
||||
{
|
||||
@@ -4020,7 +4022,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||
gspca_dev->cam.mode_framerates = sd->bridge == BRIDGE_TP6800 ?
|
||||
framerates : framerates_6810;
|
||||
|
||||
sd->framerate = 30; /* default: 30 fps */
|
||||
sd->framerate = DEFAULT_FRAME_RATE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4803,7 +4805,7 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev,
|
||||
int fr, i;
|
||||
|
||||
if (tpf->numerator == 0 || tpf->denominator == 0)
|
||||
sd->framerate = 30;
|
||||
sd->framerate = DEFAULT_FRAME_RATE;
|
||||
else
|
||||
sd->framerate = tpf->denominator / tpf->numerator;
|
||||
|
||||
|
@@ -53,7 +53,6 @@ struct sd {
|
||||
struct v4l2_ctrl *jpegqual;
|
||||
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *work_thread;
|
||||
|
||||
u8 reg08; /* webcam compression quality */
|
||||
|
||||
@@ -6826,8 +6825,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
return gspca_dev->usb_err;
|
||||
|
||||
/* Start the transfer parameters update thread */
|
||||
sd->work_thread = create_singlethread_workqueue(KBUILD_MODNAME);
|
||||
queue_work(sd->work_thread, &sd->work);
|
||||
schedule_work(&sd->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -6838,12 +6836,9 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->work_thread != NULL) {
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
destroy_workqueue(sd->work_thread);
|
||||
mutex_lock(&gspca_dev->usb_lock);
|
||||
sd->work_thread = NULL;
|
||||
}
|
||||
mutex_unlock(&gspca_dev->usb_lock);
|
||||
flush_work(&sd->work);
|
||||
mutex_lock(&gspca_dev->usb_lock);
|
||||
if (!gspca_dev->present)
|
||||
return;
|
||||
send_unknown(gspca_dev, sd->sensor);
|
||||
|
@@ -760,7 +760,7 @@ static void hackrf_return_all_buffers(struct vb2_queue *vq,
|
||||
|
||||
static int hackrf_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers,
|
||||
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct hackrf_dev *dev = vb2_get_drv_priv(vq);
|
||||
|
||||
|
@@ -310,10 +310,6 @@ static int hdpvr_probe(struct usb_interface *interface,
|
||||
init_waitqueue_head(&dev->wait_buffer);
|
||||
init_waitqueue_head(&dev->wait_data);
|
||||
|
||||
dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
|
||||
if (!dev->workqueue)
|
||||
goto error;
|
||||
|
||||
dev->options = hdpvr_default_options;
|
||||
|
||||
if (default_video_input < HDPVR_VIDEO_INPUTS)
|
||||
@@ -404,9 +400,7 @@ reg_fail:
|
||||
#endif
|
||||
error:
|
||||
if (dev) {
|
||||
/* Destroy single thread */
|
||||
if (dev->workqueue)
|
||||
destroy_workqueue(dev->workqueue);
|
||||
flush_work(&dev->worker);
|
||||
/* this frees allocated memory */
|
||||
hdpvr_delete(dev);
|
||||
}
|
||||
@@ -427,7 +421,7 @@ static void hdpvr_disconnect(struct usb_interface *interface)
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
v4l2_device_disconnect(&dev->v4l2_dev);
|
||||
msleep(100);
|
||||
flush_workqueue(dev->workqueue);
|
||||
flush_work(&dev->worker);
|
||||
mutex_lock(&dev->io_mutex);
|
||||
hdpvr_cancel_queue(dev);
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
|
@@ -316,7 +316,7 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
|
||||
dev->status = STATUS_STREAMING;
|
||||
|
||||
INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
|
||||
queue_work(dev->workqueue, &dev->worker);
|
||||
schedule_work(&dev->worker);
|
||||
|
||||
v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
|
||||
"streaming started\n");
|
||||
@@ -350,7 +350,7 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev)
|
||||
wake_up_interruptible(&dev->wait_buffer);
|
||||
msleep(50);
|
||||
|
||||
flush_workqueue(dev->workqueue);
|
||||
flush_work(&dev->worker);
|
||||
|
||||
mutex_lock(&dev->io_mutex);
|
||||
/* kill the still outstanding urbs */
|
||||
@@ -1123,7 +1123,7 @@ static void hdpvr_device_release(struct video_device *vdev)
|
||||
|
||||
hdpvr_delete(dev);
|
||||
mutex_lock(&dev->io_mutex);
|
||||
destroy_workqueue(dev->workqueue);
|
||||
flush_work(&dev->worker);
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
|
@@ -107,8 +107,6 @@ struct hdpvr_device {
|
||||
/* waitqueue for data */
|
||||
wait_queue_head_t wait_data;
|
||||
/**/
|
||||
struct workqueue_struct *workqueue;
|
||||
/**/
|
||||
struct work_struct worker;
|
||||
/* current stream owner */
|
||||
struct v4l2_fh *owner;
|
||||
|
@@ -618,7 +618,7 @@ static int msi2500_querycap(struct file *file, void *fh,
|
||||
static int msi2500_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers,
|
||||
unsigned int *nplanes, unsigned int sizes[],
|
||||
void *alloc_ctxs[])
|
||||
struct device *alloc_devs[])
|
||||
{
|
||||
struct msi2500_dev *dev = vb2_get_drv_priv(vq);
|
||||
|
||||
|
@@ -2856,11 +2856,15 @@ static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
|
||||
const char *name, int val)
|
||||
{
|
||||
struct v4l2_control ctrl;
|
||||
struct v4l2_subdev *sd;
|
||||
|
||||
pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val);
|
||||
memset(&ctrl, 0, sizeof(ctrl));
|
||||
ctrl.id = id;
|
||||
ctrl.value = val;
|
||||
v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl);
|
||||
|
||||
v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev)
|
||||
v4l2_s_ctrl(NULL, sd->ctrl_handler, &ctrl);
|
||||
}
|
||||
|
||||
#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
|
||||
|
@@ -573,7 +573,7 @@ static void pwc_video_release(struct v4l2_device *v)
|
||||
|
||||
static int queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
int size;
|
||||
@@ -1118,8 +1118,10 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
|
||||
err_video_unreg:
|
||||
video_unregister_device(&pdev->vdev);
|
||||
#endif
|
||||
err_unregister_v4l2_dev:
|
||||
v4l2_device_unregister(&pdev->v4l2_dev);
|
||||
err_free_controls:
|
||||
|
@@ -662,7 +662,7 @@ static void s2255_fillbuff(struct s2255_vc *vc,
|
||||
|
||||
static int queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct s2255_vc *vc = vb2_get_drv_priv(vq);
|
||||
if (*nbuffers < S2255_MIN_BUFS)
|
||||
|
@@ -666,7 +666,7 @@ static const struct v4l2_ioctl_ops stk1160_ioctl_ops = {
|
||||
*/
|
||||
static int queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct stk1160 *dev = vb2_get_drv_priv(vq);
|
||||
unsigned long size;
|
||||
@@ -680,6 +680,9 @@ static int queue_setup(struct vb2_queue *vq,
|
||||
*nbuffers = clamp_t(unsigned int, *nbuffers,
|
||||
STK1160_MIN_VIDEO_BUFFERS, STK1160_MAX_VIDEO_BUFFERS);
|
||||
|
||||
if (*nplanes)
|
||||
return sizes[0] < size ? -EINVAL : 0;
|
||||
|
||||
/* This means a packed colorformat */
|
||||
*nplanes = 1;
|
||||
|
||||
|
@@ -1,13 +1,6 @@
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Product web site:
|
||||
* http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
|
||||
*
|
||||
* Copyright (c) 2013 Federico Simoncelli
|
||||
* All rights reserved.
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -20,6 +13,27 @@
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL").
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Product web site:
|
||||
* http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
|
||||
*
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*/
|
||||
|
||||
#include <sound/core.h>
|
||||
@@ -278,6 +292,9 @@ static void snd_usbtv_trigger(struct work_struct *work)
|
||||
{
|
||||
struct usbtv *chip = container_of(work, struct usbtv, snd_trigger);
|
||||
|
||||
if (!chip->snd)
|
||||
return;
|
||||
|
||||
if (atomic_read(&chip->snd_stream))
|
||||
usbtv_audio_start(chip);
|
||||
else
|
||||
@@ -378,6 +395,8 @@ err:
|
||||
|
||||
void usbtv_audio_free(struct usbtv *usbtv)
|
||||
{
|
||||
cancel_work_sync(&usbtv->snd_trigger);
|
||||
|
||||
if (usbtv->snd && usbtv->udev) {
|
||||
snd_card_free(usbtv->snd);
|
||||
usbtv->snd = NULL;
|
||||
|
@@ -1,19 +1,6 @@
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Product web site:
|
||||
* http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
|
||||
*
|
||||
* Following LWN articles were very useful in construction of this driver:
|
||||
* Video4Linux2 API series: http://lwn.net/Articles/203924/
|
||||
* videobuf2 API explanation: http://lwn.net/Articles/447435/
|
||||
* Thanks go to Jonathan Corbet for providing this quality documentation.
|
||||
* He is awesome.
|
||||
*
|
||||
* Copyright (c) 2013 Lubomir Rintel
|
||||
* All rights reserved.
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -26,6 +13,33 @@
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL").
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Product web site:
|
||||
* http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
|
||||
*
|
||||
* Following LWN articles were very useful in construction of this driver:
|
||||
* Video4Linux2 API series: http://lwn.net/Articles/203924/
|
||||
* videobuf2 API explanation: http://lwn.net/Articles/447435/
|
||||
* Thanks go to Jonathan Corbet for providing this quality documentation.
|
||||
* He is awesome.
|
||||
*
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*/
|
||||
|
||||
#include "usbtv.h"
|
||||
|
@@ -1,19 +1,6 @@
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Product web site:
|
||||
* http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
|
||||
*
|
||||
* Following LWN articles were very useful in construction of this driver:
|
||||
* Video4Linux2 API series: http://lwn.net/Articles/203924/
|
||||
* videobuf2 API explanation: http://lwn.net/Articles/447435/
|
||||
* Thanks go to Jonathan Corbet for providing this quality documentation.
|
||||
* He is awesome.
|
||||
*
|
||||
* Copyright (c) 2013 Lubomir Rintel
|
||||
* All rights reserved.
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -26,6 +13,33 @@
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL").
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Product web site:
|
||||
* http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
|
||||
*
|
||||
* Following LWN articles were very useful in construction of this driver:
|
||||
* Video4Linux2 API series: http://lwn.net/Articles/203924/
|
||||
* videobuf2 API explanation: http://lwn.net/Articles/447435/
|
||||
* Thanks go to Jonathan Corbet for providing this quality documentation.
|
||||
* He is awesome.
|
||||
*
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*/
|
||||
|
||||
#include <media/v4l2-ioctl.h>
|
||||
@@ -251,8 +265,23 @@ static int usbtv_setup_capture(struct usbtv *usbtv)
|
||||
/* Copy data from chunk into a frame buffer, deinterlacing the data
|
||||
* into every second line. Unfortunately, they don't align nicely into
|
||||
* 720 pixel lines, as the chunk is 240 words long, which is 480 pixels.
|
||||
* Therefore, we break down the chunk into two halves before copyting,
|
||||
* so that we can interleave a line if needed. */
|
||||
* Therefore, we break down the chunk into two halves before copying,
|
||||
* so that we can interleave a line if needed.
|
||||
*
|
||||
* Each "chunk" is 240 words; a word in this context equals 4 bytes.
|
||||
* Image format is YUYV/YUV 4:2:2, consisting of Y Cr Y Cb, defining two
|
||||
* pixels, the Cr and Cb shared between the two pixels, but each having
|
||||
* separate Y values. Thus, the 240 words equal 480 pixels. It therefore,
|
||||
* takes 1.5 chunks to make a 720 pixel-wide line for the frame.
|
||||
* The image is interlaced, so there is a "scan" of odd lines, followed
|
||||
* by "scan" of even numbered lines.
|
||||
*
|
||||
* Following code is writing the chunks in correct sequence, skipping
|
||||
* the rows based on "odd" value.
|
||||
* line 1: chunk[0][ 0..479] chunk[0][480..959] chunk[1][ 0..479]
|
||||
* line 3: chunk[1][480..959] chunk[2][ 0..479] chunk[2][480..959]
|
||||
* ...etc.
|
||||
*/
|
||||
static void usbtv_chunk_to_vbuf(u32 *frame, __be32 *src, int chunk_no, int odd)
|
||||
{
|
||||
int half;
|
||||
@@ -608,7 +637,7 @@ static struct v4l2_file_operations usbtv_fops = {
|
||||
|
||||
static int usbtv_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers,
|
||||
unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct usbtv *usbtv = vb2_get_drv_priv(vq);
|
||||
unsigned size = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32);
|
||||
|
@@ -1,10 +1,6 @@
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* Copyright (c) 2013 Lubomir Rintel
|
||||
* All rights reserved.
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@@ -17,6 +13,24 @@
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL").
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* Fushicai USBTV007 Audio-Video Grabber Driver
|
||||
*
|
||||
* No physical hardware was harmed running Windows during the
|
||||
* reverse-engineering activity
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@@ -88,11 +88,6 @@ MODULE_PARM_DESC(adjust_y_offset, "adjust Y offset display [core]");
|
||||
#define DBG_SCRATCH (1 << 4)
|
||||
#define DBG_FUNC (1 << 5)
|
||||
|
||||
static const int max_imgwidth = MAX_FRAME_WIDTH;
|
||||
static const int max_imgheight = MAX_FRAME_HEIGHT;
|
||||
static const int min_imgwidth = MIN_FRAME_WIDTH;
|
||||
static const int min_imgheight = MIN_FRAME_HEIGHT;
|
||||
|
||||
/* The value of 'scratch_buf_size' affects quality of the picture
|
||||
* in many ways. Shorter buffers may cause loss of data when client
|
||||
* is too slow. Larger buffers are memory-consuming and take longer
|
||||
|
@@ -188,12 +188,10 @@ static ssize_t show_hue(struct device *cd,
|
||||
{
|
||||
struct video_device *vdev = to_video_device(cd);
|
||||
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
|
||||
struct v4l2_control ctrl;
|
||||
ctrl.id = V4L2_CID_HUE;
|
||||
ctrl.value = 0;
|
||||
if (usbvision->user)
|
||||
call_all(usbvision, core, g_ctrl, &ctrl);
|
||||
return sprintf(buf, "%d\n", ctrl.value);
|
||||
s32 val = v4l2_ctrl_g_ctrl(v4l2_ctrl_find(&usbvision->hdl,
|
||||
V4L2_CID_HUE));
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
|
||||
|
||||
@@ -202,12 +200,10 @@ static ssize_t show_contrast(struct device *cd,
|
||||
{
|
||||
struct video_device *vdev = to_video_device(cd);
|
||||
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
|
||||
struct v4l2_control ctrl;
|
||||
ctrl.id = V4L2_CID_CONTRAST;
|
||||
ctrl.value = 0;
|
||||
if (usbvision->user)
|
||||
call_all(usbvision, core, g_ctrl, &ctrl);
|
||||
return sprintf(buf, "%d\n", ctrl.value);
|
||||
s32 val = v4l2_ctrl_g_ctrl(v4l2_ctrl_find(&usbvision->hdl,
|
||||
V4L2_CID_CONTRAST));
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
|
||||
|
||||
@@ -216,12 +212,10 @@ static ssize_t show_brightness(struct device *cd,
|
||||
{
|
||||
struct video_device *vdev = to_video_device(cd);
|
||||
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
|
||||
struct v4l2_control ctrl;
|
||||
ctrl.id = V4L2_CID_BRIGHTNESS;
|
||||
ctrl.value = 0;
|
||||
if (usbvision->user)
|
||||
call_all(usbvision, core, g_ctrl, &ctrl);
|
||||
return sprintf(buf, "%d\n", ctrl.value);
|
||||
s32 val = v4l2_ctrl_g_ctrl(v4l2_ctrl_find(&usbvision->hdl,
|
||||
V4L2_CID_BRIGHTNESS));
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
|
||||
|
||||
@@ -230,12 +224,10 @@ static ssize_t show_saturation(struct device *cd,
|
||||
{
|
||||
struct video_device *vdev = to_video_device(cd);
|
||||
struct usb_usbvision *usbvision = video_get_drvdata(vdev);
|
||||
struct v4l2_control ctrl;
|
||||
ctrl.id = V4L2_CID_SATURATION;
|
||||
ctrl.value = 0;
|
||||
if (usbvision->user)
|
||||
call_all(usbvision, core, g_ctrl, &ctrl);
|
||||
return sprintf(buf, "%d\n", ctrl.value);
|
||||
s32 val = v4l2_ctrl_g_ctrl(v4l2_ctrl_find(&usbvision->hdl,
|
||||
V4L2_CID_SATURATION));
|
||||
|
||||
return sprintf(buf, "%d\n", val);
|
||||
}
|
||||
static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
|
||||
|
||||
|
@@ -1674,7 +1674,7 @@ static void uvc_delete(struct uvc_device *dev)
|
||||
if (dev->vdev.dev)
|
||||
v4l2_device_unregister(&dev->vdev);
|
||||
#ifdef CONFIG_MEDIA_CONTROLLER
|
||||
if (media_devnode_is_registered(&dev->mdev.devnode))
|
||||
if (media_devnode_is_registered(dev->mdev.devnode))
|
||||
media_device_unregister(&dev->mdev);
|
||||
media_device_cleanup(&dev->mdev);
|
||||
#endif
|
||||
|
@@ -71,7 +71,7 @@ static void uvc_queue_return_buffers(struct uvc_video_queue *queue,
|
||||
|
||||
static int uvc_queue_setup(struct vb2_queue *vq,
|
||||
unsigned int *nbuffers, unsigned int *nplanes,
|
||||
unsigned int sizes[], void *alloc_ctxs[])
|
||||
unsigned int sizes[], struct device *alloc_devs[])
|
||||
{
|
||||
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
|
||||
struct uvc_streaming *stream = uvc_queue_to_stream(queue);
|
||||
|
@@ -142,6 +142,21 @@ static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
|
||||
return interval;
|
||||
}
|
||||
|
||||
static __u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format,
|
||||
const struct uvc_frame *frame)
|
||||
{
|
||||
switch (format->fcc) {
|
||||
case V4L2_PIX_FMT_NV12:
|
||||
case V4L2_PIX_FMT_YVU420:
|
||||
case V4L2_PIX_FMT_YUV420:
|
||||
case V4L2_PIX_FMT_M420:
|
||||
return frame->wWidth;
|
||||
|
||||
default:
|
||||
return format->bpp * frame->wWidth / 8;
|
||||
}
|
||||
}
|
||||
|
||||
static int uvc_v4l2_try_format(struct uvc_streaming *stream,
|
||||
struct v4l2_format *fmt, struct uvc_streaming_control *probe,
|
||||
struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
|
||||
@@ -245,7 +260,7 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream,
|
||||
fmt->fmt.pix.width = frame->wWidth;
|
||||
fmt->fmt.pix.height = frame->wHeight;
|
||||
fmt->fmt.pix.field = V4L2_FIELD_NONE;
|
||||
fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
|
||||
fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
|
||||
fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
|
||||
fmt->fmt.pix.colorspace = format->colorspace;
|
||||
fmt->fmt.pix.priv = 0;
|
||||
@@ -282,7 +297,7 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream,
|
||||
fmt->fmt.pix.width = frame->wWidth;
|
||||
fmt->fmt.pix.height = frame->wHeight;
|
||||
fmt->fmt.pix.field = V4L2_FIELD_NONE;
|
||||
fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
|
||||
fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
|
||||
fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
|
||||
fmt->fmt.pix.colorspace = format->colorspace;
|
||||
fmt->fmt.pix.priv = 0;
|
||||
|
@@ -1470,6 +1470,7 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
|
||||
|
||||
switch (dev->speed) {
|
||||
case USB_SPEED_SUPER:
|
||||
case USB_SPEED_SUPER_PLUS:
|
||||
return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval);
|
||||
case USB_SPEED_HIGH:
|
||||
psize = usb_endpoint_maxp(&ep->desc);
|
||||
|
Verwijs in nieuw issue
Block a user