drm/i915: Change I2C api to pass around i2c_adapters
The existing API passed around intel_i2c_chan pointers, which are dependent on the i2c bit-banging algo. This precluded the driver from using outputs which use a different algo. Switching to the more general i2c_adpater allows the driver to support non bit-banging DDC. This also required moving the slave address into the output private structures. Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
b99e228d35
commit
f9c10a9b96
12 changed files with 118 additions and 113 deletions
|
@ -37,7 +37,7 @@ struct intel_dvo_device {
|
|||
/* GPIO register used for i2c bus to control this device */
|
||||
u32 gpio;
|
||||
int slave_addr;
|
||||
struct intel_i2c_chan *i2c_bus;
|
||||
struct i2c_adapter *i2c_bus;
|
||||
|
||||
const struct intel_dvo_dev_ops *dev_ops;
|
||||
void *dev_priv;
|
||||
|
@ -52,7 +52,7 @@ struct intel_dvo_dev_ops {
|
|||
* Returns NULL if the device does not exist.
|
||||
*/
|
||||
bool (*init)(struct intel_dvo_device *dvo,
|
||||
struct intel_i2c_chan *i2cbus);
|
||||
struct i2c_adapter *i2cbus);
|
||||
|
||||
/*
|
||||
* Called to allow the output a chance to create properties after the
|
||||
|
|
|
@ -176,19 +176,20 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode);
|
|||
|
||||
static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val)
|
||||
{
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
u8 out_buf[2];
|
||||
u8 in_buf[2];
|
||||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = out_buf,
|
||||
},
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = in_buf,
|
||||
|
@ -208,10 +209,11 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val)
|
|||
|
||||
static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val)
|
||||
{
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
uint8_t out_buf[2];
|
||||
struct i2c_msg msg = {
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = out_buf,
|
||||
|
@ -228,8 +230,9 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val)
|
|||
|
||||
/** Probes for a CH7017 on the given bus and slave address. */
|
||||
static bool ch7017_init(struct intel_dvo_device *dvo,
|
||||
struct intel_i2c_chan *i2cbus)
|
||||
struct i2c_adapter *adapter)
|
||||
{
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
struct ch7017_priv *priv;
|
||||
uint8_t val;
|
||||
|
||||
|
@ -237,8 +240,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo,
|
|||
if (priv == NULL)
|
||||
return false;
|
||||
|
||||
dvo->i2c_bus = i2cbus;
|
||||
dvo->i2c_bus->slave_addr = dvo->slave_addr;
|
||||
dvo->i2c_bus = adapter;
|
||||
dvo->dev_priv = priv;
|
||||
|
||||
if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val))
|
||||
|
@ -248,7 +250,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo,
|
|||
val != CH7018_DEVICE_ID_VALUE &&
|
||||
val != CH7019_DEVICE_ID_VALUE) {
|
||||
DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n",
|
||||
val, i2cbus->adapter.name,i2cbus->slave_addr);
|
||||
val, i2cbus->adapter.name,dvo->slave_addr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,19 +123,20 @@ static char *ch7xxx_get_id(uint8_t vid)
|
|||
static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
||||
{
|
||||
struct ch7xxx_priv *ch7xxx= dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
u8 out_buf[2];
|
||||
u8 in_buf[2];
|
||||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = out_buf,
|
||||
},
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = in_buf,
|
||||
|
@ -152,7 +153,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
|||
|
||||
if (!ch7xxx->quiet) {
|
||||
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -161,10 +162,11 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
|||
static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
||||
{
|
||||
struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
uint8_t out_buf[2];
|
||||
struct i2c_msg msg = {
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = out_buf,
|
||||
|
@ -178,14 +180,14 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
|||
|
||||
if (!ch7xxx->quiet) {
|
||||
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ch7xxx_init(struct intel_dvo_device *dvo,
|
||||
struct intel_i2c_chan *i2cbus)
|
||||
struct i2c_adapter *adapter)
|
||||
{
|
||||
/* this will detect the CH7xxx chip on the specified i2c bus */
|
||||
struct ch7xxx_priv *ch7xxx;
|
||||
|
@ -196,8 +198,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo,
|
|||
if (ch7xxx == NULL)
|
||||
return false;
|
||||
|
||||
dvo->i2c_bus = i2cbus;
|
||||
dvo->i2c_bus->slave_addr = dvo->slave_addr;
|
||||
dvo->i2c_bus = adapter;
|
||||
dvo->dev_priv = ch7xxx;
|
||||
ch7xxx->quiet = true;
|
||||
|
||||
|
@ -207,7 +208,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo,
|
|||
name = ch7xxx_get_id(vendor);
|
||||
if (!name) {
|
||||
DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
|
||||
vendor, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
vendor, adapter->name, dvo->slave_addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -217,7 +218,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo,
|
|||
|
||||
if (device != CH7xxx_DID) {
|
||||
DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
|
||||
vendor, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
vendor, adapter->name, dvo->slave_addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,13 +169,14 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo);
|
|||
static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
|
||||
{
|
||||
struct ivch_priv *priv = dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
u8 out_buf[1];
|
||||
u8 in_buf[2];
|
||||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 0,
|
||||
},
|
||||
|
@ -186,7 +187,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
|
|||
.buf = out_buf,
|
||||
},
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = I2C_M_RD | I2C_M_NOSTART,
|
||||
.len = 2,
|
||||
.buf = in_buf,
|
||||
|
@ -202,7 +203,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
|
|||
|
||||
if (!priv->quiet) {
|
||||
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -211,10 +212,11 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
|
|||
static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
|
||||
{
|
||||
struct ivch_priv *priv = dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
u8 out_buf[3];
|
||||
struct i2c_msg msg = {
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 3,
|
||||
.buf = out_buf,
|
||||
|
@ -229,7 +231,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
|
|||
|
||||
if (!priv->quiet) {
|
||||
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -237,7 +239,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
|
|||
|
||||
/** Probes the given bus and slave address for an ivch */
|
||||
static bool ivch_init(struct intel_dvo_device *dvo,
|
||||
struct intel_i2c_chan *i2cbus)
|
||||
struct i2c_adapter *adapter)
|
||||
{
|
||||
struct ivch_priv *priv;
|
||||
uint16_t temp;
|
||||
|
@ -246,8 +248,7 @@ static bool ivch_init(struct intel_dvo_device *dvo,
|
|||
if (priv == NULL)
|
||||
return false;
|
||||
|
||||
dvo->i2c_bus = i2cbus;
|
||||
dvo->i2c_bus->slave_addr = dvo->slave_addr;
|
||||
dvo->i2c_bus = adapter;
|
||||
dvo->dev_priv = priv;
|
||||
priv->quiet = true;
|
||||
|
||||
|
|
|
@ -76,19 +76,20 @@ struct sil164_priv {
|
|||
static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
||||
{
|
||||
struct sil164_priv *sil = dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
u8 out_buf[2];
|
||||
u8 in_buf[2];
|
||||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = out_buf,
|
||||
},
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = in_buf,
|
||||
|
@ -105,7 +106,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
|||
|
||||
if (!sil->quiet) {
|
||||
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -113,10 +114,11 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
|||
static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
||||
{
|
||||
struct sil164_priv *sil= dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
uint8_t out_buf[2];
|
||||
struct i2c_msg msg = {
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = out_buf,
|
||||
|
@ -130,7 +132,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
|||
|
||||
if (!sil->quiet) {
|
||||
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -138,7 +140,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
|||
|
||||
/* Silicon Image 164 driver for chip on i2c bus */
|
||||
static bool sil164_init(struct intel_dvo_device *dvo,
|
||||
struct intel_i2c_chan *i2cbus)
|
||||
struct i2c_adapter *adapter)
|
||||
{
|
||||
/* this will detect the SIL164 chip on the specified i2c bus */
|
||||
struct sil164_priv *sil;
|
||||
|
@ -148,8 +150,7 @@ static bool sil164_init(struct intel_dvo_device *dvo,
|
|||
if (sil == NULL)
|
||||
return false;
|
||||
|
||||
dvo->i2c_bus = i2cbus;
|
||||
dvo->i2c_bus->slave_addr = dvo->slave_addr;
|
||||
dvo->i2c_bus = adapter;
|
||||
dvo->dev_priv = sil;
|
||||
sil->quiet = true;
|
||||
|
||||
|
@ -158,7 +159,7 @@ static bool sil164_init(struct intel_dvo_device *dvo,
|
|||
|
||||
if (ch != (SIL164_VID & 0xff)) {
|
||||
DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
|
||||
ch, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
ch, adapter->name, dvo->slave_addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -167,7 +168,7 @@ static bool sil164_init(struct intel_dvo_device *dvo,
|
|||
|
||||
if (ch != (SIL164_DID & 0xff)) {
|
||||
DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
|
||||
ch, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
ch, adapter->name, dvo->slave_addr);
|
||||
goto out;
|
||||
}
|
||||
sil->quiet = false;
|
||||
|
|
|
@ -101,19 +101,20 @@ struct tfp410_priv {
|
|||
static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
||||
{
|
||||
struct tfp410_priv *tfp = dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
u8 out_buf[2];
|
||||
u8 in_buf[2];
|
||||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = out_buf,
|
||||
},
|
||||
{
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = in_buf,
|
||||
|
@ -130,7 +131,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
|||
|
||||
if (!tfp->quiet) {
|
||||
DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -138,10 +139,11 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
|
|||
static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
||||
{
|
||||
struct tfp410_priv *tfp = dvo->dev_priv;
|
||||
struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
|
||||
struct i2c_adapter *adapter = dvo->i2c_bus;
|
||||
struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter);
|
||||
uint8_t out_buf[2];
|
||||
struct i2c_msg msg = {
|
||||
.addr = i2cbus->slave_addr,
|
||||
.addr = dvo->slave_addr,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = out_buf,
|
||||
|
@ -155,7 +157,7 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
|
|||
|
||||
if (!tfp->quiet) {
|
||||
DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
|
||||
addr, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
addr, i2cbus->adapter.name, dvo->slave_addr);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -174,7 +176,7 @@ static int tfp410_getid(struct intel_dvo_device *dvo, int addr)
|
|||
|
||||
/* Ti TFP410 driver for chip on i2c bus */
|
||||
static bool tfp410_init(struct intel_dvo_device *dvo,
|
||||
struct intel_i2c_chan *i2cbus)
|
||||
struct i2c_adapter *adapter)
|
||||
{
|
||||
/* this will detect the tfp410 chip on the specified i2c bus */
|
||||
struct tfp410_priv *tfp;
|
||||
|
@ -184,20 +186,19 @@ static bool tfp410_init(struct intel_dvo_device *dvo,
|
|||
if (tfp == NULL)
|
||||
return false;
|
||||
|
||||
dvo->i2c_bus = i2cbus;
|
||||
dvo->i2c_bus->slave_addr = dvo->slave_addr;
|
||||
dvo->i2c_bus = adapter;
|
||||
dvo->dev_priv = tfp;
|
||||
tfp->quiet = true;
|
||||
|
||||
if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
|
||||
DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n",
|
||||
id, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
id, adapter->name, dvo->slave_addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
|
||||
DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n",
|
||||
id, i2cbus->adapter.name, i2cbus->slave_addr);
|
||||
id, adapter->name, dvo->slave_addr);
|
||||
goto out;
|
||||
}
|
||||
tfp->quiet = false;
|
||||
|
|
|
@ -65,7 +65,6 @@ struct intel_i2c_chan {
|
|||
u32 reg; /* GPIO reg */
|
||||
struct i2c_adapter adapter;
|
||||
struct i2c_algo_bit_data algo;
|
||||
u8 slave_addr;
|
||||
};
|
||||
|
||||
struct intel_framebuffer {
|
||||
|
@ -79,8 +78,8 @@ struct intel_output {
|
|||
|
||||
struct drm_encoder enc;
|
||||
int type;
|
||||
struct intel_i2c_chan *i2c_bus; /* for control functions */
|
||||
struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
|
||||
struct i2c_adapter *i2c_bus;
|
||||
struct i2c_adapter *ddc_bus;
|
||||
bool load_detect_temp;
|
||||
bool needs_tv_clock;
|
||||
void *dev_priv;
|
||||
|
@ -104,9 +103,9 @@ struct intel_crtc {
|
|||
#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
|
||||
#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
|
||||
|
||||
struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
const char *name);
|
||||
void intel_i2c_destroy(struct intel_i2c_chan *chan);
|
||||
struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
const char *name);
|
||||
void intel_i2c_destroy(struct i2c_adapter *adapter);
|
||||
int intel_ddc_get_modes(struct intel_output *intel_output);
|
||||
extern bool intel_ddc_probe(struct intel_output *intel_output);
|
||||
void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
|
||||
|
|
|
@ -384,10 +384,9 @@ void intel_dvo_init(struct drm_device *dev)
|
|||
{
|
||||
struct intel_output *intel_output;
|
||||
struct intel_dvo_device *dvo;
|
||||
struct intel_i2c_chan *i2cbus = NULL;
|
||||
struct i2c_adapter *i2cbus = NULL;
|
||||
int ret = 0;
|
||||
int i;
|
||||
int gpio_inited = 0;
|
||||
int encoder_type = DRM_MODE_ENCODER_NONE;
|
||||
intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
|
||||
if (!intel_output)
|
||||
|
@ -420,14 +419,11 @@ void intel_dvo_init(struct drm_device *dev)
|
|||
* It appears that everything is on GPIOE except for panels
|
||||
* on i830 laptops, which are on GPIOB (DVOA).
|
||||
*/
|
||||
if (gpio_inited != gpio) {
|
||||
if (i2cbus != NULL)
|
||||
intel_i2c_destroy(i2cbus);
|
||||
if (!(i2cbus = intel_i2c_create(dev, gpio,
|
||||
gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) {
|
||||
continue;
|
||||
}
|
||||
gpio_inited = gpio;
|
||||
if (i2cbus != NULL)
|
||||
intel_i2c_destroy(i2cbus);
|
||||
if (!(i2cbus = intel_i2c_create(dev, gpio,
|
||||
gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dvo->dev_ops!= NULL)
|
||||
|
|
|
@ -139,7 +139,7 @@ intel_hdmi_edid_detect(struct drm_connector *connector)
|
|||
enum drm_connector_status status = connector_status_disconnected;
|
||||
|
||||
edid = drm_get_edid(&intel_output->base,
|
||||
&intel_output->ddc_bus->adapter);
|
||||
intel_output->ddc_bus);
|
||||
hdmi_priv->has_hdmi_sink = false;
|
||||
if (edid) {
|
||||
if (edid->digital) {
|
||||
|
|
|
@ -124,6 +124,7 @@ static void set_data(void *data, int state_high)
|
|||
* @output: driver specific output device
|
||||
* @reg: GPIO reg to use
|
||||
* @name: name for this bus
|
||||
* @slave_addr: slave address (if fixed)
|
||||
*
|
||||
* Creates and registers a new i2c bus with the Linux i2c layer, for use
|
||||
* in output probing and control (e.g. DDC or SDVO control functions).
|
||||
|
@ -139,8 +140,8 @@ static void set_data(void *data, int state_high)
|
|||
* %GPIOH
|
||||
* see PRM for details on how these different busses are used.
|
||||
*/
|
||||
struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
const char *name)
|
||||
struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
||||
const char *name)
|
||||
{
|
||||
struct intel_i2c_chan *chan;
|
||||
|
||||
|
@ -174,7 +175,7 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
|||
intel_i2c_quirk_set(dev, false);
|
||||
udelay(20);
|
||||
|
||||
return chan;
|
||||
return &chan->adapter;
|
||||
|
||||
out_free:
|
||||
kfree(chan);
|
||||
|
@ -187,11 +188,16 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
|
|||
*
|
||||
* Unregister the adapter from the i2c layer, then free the structure.
|
||||
*/
|
||||
void intel_i2c_destroy(struct intel_i2c_chan *chan)
|
||||
void intel_i2c_destroy(struct i2c_adapter *adapter)
|
||||
{
|
||||
if (!chan)
|
||||
struct intel_i2c_chan *chan;
|
||||
|
||||
if (!adapter)
|
||||
return;
|
||||
|
||||
chan = container_of(adapter,
|
||||
struct intel_i2c_chan,
|
||||
adapter);
|
||||
i2c_del_adapter(&chan->adapter);
|
||||
kfree(chan);
|
||||
}
|
||||
|
|
|
@ -53,10 +53,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)
|
|||
}
|
||||
};
|
||||
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true);
|
||||
ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2);
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false);
|
||||
|
||||
intel_i2c_quirk_set(intel_output->base.dev, true);
|
||||
ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
|
||||
intel_i2c_quirk_set(intel_output->base.dev, false);
|
||||
if (ret == 2)
|
||||
return true;
|
||||
|
||||
|
@ -74,10 +73,9 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
|
|||
struct edid *edid;
|
||||
int ret = 0;
|
||||
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true);
|
||||
edid = drm_get_edid(&intel_output->base,
|
||||
&intel_output->ddc_bus->adapter);
|
||||
intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false);
|
||||
intel_i2c_quirk_set(intel_output->base.dev, true);
|
||||
edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
|
||||
intel_i2c_quirk_set(intel_output->base.dev, false);
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(&intel_output->base,
|
||||
edid);
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
#undef SDVO_DEBUG
|
||||
#define I915_SDVO "i915_sdvo"
|
||||
struct intel_sdvo_priv {
|
||||
struct intel_i2c_chan *i2c_bus;
|
||||
int slaveaddr;
|
||||
struct i2c_adapter *i2c_bus;
|
||||
u8 slave_addr;
|
||||
|
||||
/* Register for the SDVO device: SDVOB or SDVOC */
|
||||
int output_device;
|
||||
|
@ -146,13 +146,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
|
|||
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = sdvo_priv->i2c_bus->slave_addr,
|
||||
.addr = sdvo_priv->slave_addr >> 1,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = out_buf,
|
||||
},
|
||||
{
|
||||
.addr = sdvo_priv->i2c_bus->slave_addr,
|
||||
.addr = sdvo_priv->slave_addr >> 1,
|
||||
.flags = I2C_M_RD,
|
||||
.len = 1,
|
||||
.buf = buf,
|
||||
|
@ -162,7 +162,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
|
|||
out_buf[0] = addr;
|
||||
out_buf[1] = 0;
|
||||
|
||||
if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2)
|
||||
if ((ret = i2c_transfer(sdvo_priv->i2c_bus, msgs, 2)) == 2)
|
||||
{
|
||||
*ch = buf[0];
|
||||
return true;
|
||||
|
@ -175,10 +175,11 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
|
|||
static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
|
||||
u8 ch)
|
||||
{
|
||||
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
||||
u8 out_buf[2];
|
||||
struct i2c_msg msgs[] = {
|
||||
{
|
||||
.addr = intel_output->i2c_bus->slave_addr,
|
||||
.addr = sdvo_priv->slave_addr >> 1,
|
||||
.flags = 0,
|
||||
.len = 2,
|
||||
.buf = out_buf,
|
||||
|
@ -188,7 +189,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
|
|||
out_buf[0] = addr;
|
||||
out_buf[1] = ch;
|
||||
|
||||
if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1)
|
||||
if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1371,7 +1372,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
|
|||
|
||||
intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
|
||||
edid = drm_get_edid(&intel_output->base,
|
||||
&intel_output->ddc_bus->adapter);
|
||||
intel_output->ddc_bus);
|
||||
if (edid != NULL) {
|
||||
sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
|
||||
kfree(edid);
|
||||
|
@ -1709,7 +1710,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
|
|||
|
||||
list_for_each_entry(connector,
|
||||
&dev->mode_config.connector_list, head) {
|
||||
if (to_intel_output(connector)->ddc_bus == chan) {
|
||||
if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
|
||||
intel_output = to_intel_output(connector);
|
||||
break;
|
||||
}
|
||||
|
@ -1723,7 +1724,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
|
|||
struct intel_output *intel_output;
|
||||
struct intel_sdvo_priv *sdvo_priv;
|
||||
struct i2c_algo_bit_data *algo_data;
|
||||
struct i2c_algorithm *algo;
|
||||
const struct i2c_algorithm *algo;
|
||||
|
||||
algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
|
||||
intel_output =
|
||||
|
@ -1733,7 +1734,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
|
|||
return -EINVAL;
|
||||
|
||||
sdvo_priv = intel_output->dev_priv;
|
||||
algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo;
|
||||
algo = intel_output->i2c_bus->algo;
|
||||
|
||||
intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
|
||||
return algo->master_xfer(i2c_adap, msgs, num);
|
||||
|
@ -1785,12 +1786,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
struct drm_connector *connector;
|
||||
struct intel_output *intel_output;
|
||||
struct intel_sdvo_priv *sdvo_priv;
|
||||
struct intel_i2c_chan *i2cbus = NULL;
|
||||
struct intel_i2c_chan *ddcbus = NULL;
|
||||
struct i2c_adapter *i2cbus = NULL;
|
||||
struct i2c_adapter *ddcbus = NULL;
|
||||
|
||||
int connector_type;
|
||||
u8 ch[0x40];
|
||||
int i;
|
||||
int encoder_type, output_id;
|
||||
int encoder_type;
|
||||
u8 slave_addr;
|
||||
|
||||
intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
|
||||
|
@ -1802,25 +1804,23 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
intel_output->type = INTEL_OUTPUT_SDVO;
|
||||
|
||||
/* setup the DDC bus. */
|
||||
if (output_device == SDVOB)
|
||||
if (output_device == SDVOB) {
|
||||
i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
|
||||
else
|
||||
slave_addr = 0x38;
|
||||
} else {
|
||||
i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
|
||||
|
||||
slave_addr = 0x39;
|
||||
}
|
||||
|
||||
if (!i2cbus)
|
||||
goto err_inteloutput;
|
||||
|
||||
slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
|
||||
sdvo_priv->i2c_bus = i2cbus;
|
||||
sdvo_priv->slave_addr = slave_addr;
|
||||
|
||||
if (output_device == SDVOB) {
|
||||
output_id = 1;
|
||||
} else {
|
||||
output_id = 2;
|
||||
}
|
||||
sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1;
|
||||
sdvo_priv->output_device = output_device;
|
||||
intel_output->i2c_bus = i2cbus;
|
||||
intel_output->i2c_bus = sdvo_priv->i2c_bus;
|
||||
intel_output->dev_priv = sdvo_priv;
|
||||
|
||||
/* Read the regs to test if we can talk to the device */
|
||||
|
@ -1843,8 +1843,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
goto err_i2c;
|
||||
|
||||
intel_sdvo_i2c_bit_algo.functionality =
|
||||
intel_output->i2c_bus->adapter.algo->functionality;
|
||||
ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo;
|
||||
intel_output->i2c_bus->algo->functionality;
|
||||
ddcbus->algo = &intel_sdvo_i2c_bit_algo;
|
||||
intel_output->ddc_bus = ddcbus;
|
||||
|
||||
/* In defaut case sdvo lvds is false */
|
||||
|
|
Loading…
Reference in a new issue