Commit 09aa2609 authored by Javier Martinez Canillas's avatar Javier Martinez Canillas Committed by Mauro Carvalho Chehab

[media] tvp5150: Initialize the chip on probe

After power-up, the tvp5150 decoder is in a unknown state until the
RESETB pin is driven LOW which reset all the registers and restarts
the chip's internal state machine.

The init sequence has some timing constraints and the RESETB signal
can only be used if the PDN (Power-down) pin is first released.

So, the initialization sequence is as follows:

1- PDN (active-low) is driven HIGH so the chip is power-up
2- A 20 ms delay is needed before sending a RESETB (active-low) signal.
3- The RESETB pulse duration is 500 ns.
4- A 200 us delay is needed for the I2C client to be active after reset.

This patch used as a reference the logic in the IGEPv2 board file from
the ISEE 2.6.37 vendor tree.
Signed-off-by: default avatarJavier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 367298c6
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <media/v4l2-async.h> #include <media/v4l2-async.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
...@@ -1175,6 +1176,36 @@ static int tvp5150_detect_version(struct tvp5150 *core) ...@@ -1175,6 +1176,36 @@ static int tvp5150_detect_version(struct tvp5150 *core)
return 0; return 0;
} }
static int tvp5150_init(struct i2c_client *c)
{
struct gpio_desc *pdn_gpio;
struct gpio_desc *reset_gpio;
pdn_gpio = devm_gpiod_get_optional(&c->dev, "pdn", GPIOD_OUT_HIGH);
if (IS_ERR(pdn_gpio))
return PTR_ERR(pdn_gpio);
if (pdn_gpio) {
gpiod_set_value_cansleep(pdn_gpio, 0);
/* Delay time between power supplies active and reset */
msleep(20);
}
reset_gpio = devm_gpiod_get_optional(&c->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(reset_gpio))
return PTR_ERR(reset_gpio);
if (reset_gpio) {
/* RESETB pulse duration */
ndelay(500);
gpiod_set_value_cansleep(reset_gpio, 0);
/* Delay time between end of reset to I2C active */
usleep_range(200, 250);
}
return 0;
}
static int tvp5150_probe(struct i2c_client *c, static int tvp5150_probe(struct i2c_client *c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -1187,6 +1218,10 @@ static int tvp5150_probe(struct i2c_client *c, ...@@ -1187,6 +1218,10 @@ static int tvp5150_probe(struct i2c_client *c,
I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
return -EIO; return -EIO;
res = tvp5150_init(c);
if (res)
return res;
core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL); core = devm_kzalloc(&c->dev, sizeof(*core), GFP_KERNEL);
if (!core) if (!core)
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment