summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJonathan Gray <jsg@jsg.id.au>2013-03-18 13:54:08 +1100
committerJonathan Gray <jsg@jsg.id.au>2013-03-18 13:54:08 +1100
commit0bc727776cfa186778886ee856d8008cafb9ca63 (patch)
tree1ca52a461b855887ead1772f797dd397ab02a31c /sys
parent8a9c72f304a643d7d4d2a081b128a2bfc08776ee (diff)
unstub sdvo i2c functions
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/i915/intel_sdvo.c102
1 files changed, 59 insertions, 43 deletions
diff --git a/sys/dev/pci/drm/i915/intel_sdvo.c b/sys/dev/pci/drm/i915/intel_sdvo.c
index 7059667127a..e68acaa3faa 100644
--- a/sys/dev/pci/drm/i915/intel_sdvo.c
+++ b/sys/dev/pci/drm/i915/intel_sdvo.c
@@ -317,6 +317,10 @@ uint16_t intel_sdvo_get_hotplug_support(struct intel_sdvo *);
void intel_sdvo_unselect_i2c_bus(struct intel_sdvo *);
u8 intel_sdvo_get_slave_addr(struct drm_device *, struct intel_sdvo *);
void intel_sdvo_output_cleanup(struct intel_sdvo *);
+int intel_sdvo_ddc_proxy_acquire_bus(void *, int);
+void intel_sdvo_ddc_proxy_release_bus(void *, int);
+int intel_sdvo_ddc_proxy_exec(void *, i2c_op_t, i2c_addr_t,
+ const void *, size_t, void *, size_t, int);
struct intel_sdvo *
to_intel_sdvo(struct drm_encoder *encoder)
@@ -551,16 +555,21 @@ static const char *cmd_status_names[] = {
"Scaling not supported"
};
+struct i2c_msg {
+ i2c_op_t op;
+ i2c_addr_t addr;
+ void *buf;
+ size_t len;
+};
+
bool
intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
const void *args, int args_len)
{
- printf("%s stub\n", __func__);
- return false;
-#ifdef notyet
u8 *buf, status;
struct i2c_msg *msgs;
- int i, ret = true;
+ int i, ret = true, x;
+ uint8_t c = 0;
/* Would be simpler to allocate both in one go ? */
buf = (u8 *)malloc(args_len * 2 + 2, M_DRM,
@@ -578,15 +587,15 @@ intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len);
for (i = 0; i < args_len; i++) {
+ msgs[i].op = I2C_OP_WRITE_WITH_STOP;
msgs[i].addr = intel_sdvo->slave_addr;
- msgs[i].flags = 0;
msgs[i].len = 2;
msgs[i].buf = buf + 2 *i;
buf[2*i + 0] = SDVO_I2C_ARG_0 - i;
buf[2*i + 1] = ((u8*)args)[i];
}
+ msgs[i].op = I2C_OP_WRITE_WITH_STOP;
msgs[i].addr = intel_sdvo->slave_addr;
- msgs[i].flags = 0;
msgs[i].len = 2;
msgs[i].buf = buf + 2*i;
buf[2*i + 0] = SDVO_I2C_OPCODE;
@@ -594,33 +603,31 @@ intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd,
/* the following two are to read the response */
status = SDVO_I2C_CMD_STATUS;
+ msgs[i+1].op = I2C_OP_WRITE_WITH_STOP;
msgs[i+1].addr = intel_sdvo->slave_addr;
- msgs[i+1].flags = 0;
msgs[i+1].len = 1;
msgs[i+1].buf = &status;
+ msgs[i+2].op = I2C_OP_READ_WITH_STOP;
msgs[i+2].addr = intel_sdvo->slave_addr;
- msgs[i+2].flags = I2C_M_RD;
msgs[i+2].len = 1;
msgs[i+2].buf = &status;
- ret = i2c_transfer(intel_sdvo->i2c, msgs, i+3);
- if (ret < 0) {
- DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
- ret = false;
- goto out;
- }
- if (ret != i+3) {
- /* failure in I2C transfer */
- DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3);
- ret = false;
+ iic_acquire_bus(intel_sdvo->i2c, 0);
+ for (x = 0; x < i+3; x++) {
+ ret = iic_exec(intel_sdvo->i2c, msgs[x].op, msgs[x].addr,
+ &c, 1, msgs[x].buf, msgs[x].len, 0);
+ if (ret) {
+ DRM_DEBUG_KMS("sdvo i2c transfer failed\n");
+ ret = false;
+ break;
+ }
}
+ iic_release_bus(intel_sdvo->i2c, 0);
-out:
free(msgs, M_DRM);
free(buf, M_DRM);
return ret;
-#endif
}
bool
@@ -2287,8 +2294,6 @@ void
intel_sdvo_select_i2c_bus(struct inteldrm_softc *dev_priv,
struct intel_sdvo *sdvo, u32 reg)
{
- printf("%s stub\n", __func__);
-#ifdef notyet
struct sdvo_device_mapping *mapping;
u8 pin;
@@ -2304,6 +2309,7 @@ intel_sdvo_select_i2c_bus(struct inteldrm_softc *dev_priv,
sdvo->i2c = intel_gmbus_get_adapter(dev_priv, pin);
+#ifdef notyet
/* With gmbus we should be able to drive sdvo i2c at 2MHz, but somehow
* our code totally fails once we start using gmbus. Hence fall back to
* bit banging for now. */
@@ -2858,40 +2864,43 @@ intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo,
return true;
}
-#ifdef notyet
int
-intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter,
- struct i2c_msg *msgs,
- int num)
+intel_sdvo_ddc_proxy_acquire_bus(void *cookie, int flags)
{
- struct intel_sdvo *sdvo = adapter->algo_data;
-
- if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
- return -EIO;
+ struct intel_sdvo *sdvo = cookie;
+ struct i2c_controller *i2c = sdvo->i2c;
- return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num);
+ return ((i2c->ic_acquire_bus)(i2c->ic_cookie, flags));
}
-u32
-intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter)
+void
+intel_sdvo_ddc_proxy_release_bus(void *cookie, int flags)
{
- struct intel_sdvo *sdvo = adapter->algo_data;
- return sdvo->i2c->algo->functionality(sdvo->i2c);
+ struct intel_sdvo *sdvo = cookie;
+ struct i2c_controller *i2c = sdvo->i2c;
+
+ (i2c->ic_release_bus)(i2c->ic_cookie, flags);
}
-static const struct i2c_algorithm intel_sdvo_ddc_proxy = {
- .master_xfer = intel_sdvo_ddc_proxy_xfer,
- .functionality = intel_sdvo_ddc_proxy_func
-};
-#endif
+int
+intel_sdvo_ddc_proxy_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
+ const void *cmdbuf, size_t cmdlen, void *buffer, size_t len, int flags)
+{
+ struct intel_sdvo *sdvo = cookie;
+ struct i2c_controller *i2c = sdvo->i2c;
+
+ if (!intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus))
+ return -EIO;
+
+ return ((i2c->ic_exec)(i2c->ic_cookie,
+ op, addr, cmdbuf, cmdlen, buffer, len, flags));
+}
bool
intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
struct drm_device *dev)
{
- printf("%s stub\n", __func__);
- return false;
-#ifdef notyet
+#if 0
sdvo->ddc.owner = THIS_MODULE;
sdvo->ddc.class = I2C_CLASS_DDC;
snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy");
@@ -2900,6 +2909,13 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo *sdvo,
sdvo->ddc.algo = &intel_sdvo_ddc_proxy;
return i2c_add_adapter(&sdvo->ddc) == 0;
+#else
+ sdvo->ddc.ic_cookie = sdvo;
+ sdvo->ddc.ic_acquire_bus = intel_sdvo_ddc_proxy_acquire_bus;
+ sdvo->ddc.ic_release_bus = intel_sdvo_ddc_proxy_release_bus;
+ sdvo->ddc.ic_exec = intel_sdvo_ddc_proxy_exec;
+
+ return true;
#endif
}