static int tpd_read_edid(struct omap_dss_device *dssdev, u8 *edid, int len) { struct panel_drv_data *ddata = to_panel_data(dssdev); struct omap_dss_device *in = ddata->in; int r = 0; if (!gpio_get_value_cansleep(ddata->hpd_gpio)) return -ENODEV; if (gpio_is_valid(ddata->ls_oe_gpio)) gpio_set_value_cansleep(ddata->ls_oe_gpio, 1); config_demux(dssdev->dev, SEL_HDMI); r = in->ops.hdmi->read_edid(in, edid, len); config_demux(dssdev->dev, SEL_I2C2); if (gpio_is_valid(ddata->ls_oe_gpio)) gpio_set_value_cansleep(ddata->ls_oe_gpio, 0); return r; }
static int tpd_probe(struct platform_device *pdev) { struct omap_dss_device *in, *dssdev; struct panel_drv_data *ddata; int r; ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) return -ENOMEM; platform_set_drvdata(pdev, ddata); if (dev_get_platdata(&pdev->dev)) { r = tpd_probe_pdata(pdev); if (r) return r; } else if (pdev->dev.of_node) { r = tpd_probe_of(pdev); if (r) return r; } else { return -ENODEV; } /* * initialize the SEL_HDMI_I2C2 line going to the demux. Configure the * demux to select the I2C2 bus */ r = sel_hdmi_i2c2_init(&pdev->dev); if (r) return r; config_demux(&pdev->dev, SEL_I2C2); r = devm_gpio_request_one(&pdev->dev, ddata->ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd"); if (r) goto err_gpio; if (gpio_is_valid(ddata->ls_oe_gpio)) { r = devm_gpio_request_one(&pdev->dev, ddata->ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe"); if (r) goto err_gpio; } r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd"); if (r) goto err_gpio; /* * we see some low voltage glitches on the HPD_B line before it * stabalizes to around 5V. We see the effects of this glitch on the * HPD_A side, and hence on the gpio on DRA7x. The glitch is quite short * in duration, but it takes a while for the voltage to go down back to * 0 volts, we set a debounce value of 1 millisecond to prevent this, * the reason for the glitch not being taken care of by the TPD chip * needs to be investigated */ r = gpio_set_debounce(ddata->hpd_gpio, HPD_DEBOUNCE_TIME); if (r) goto err_debounce; dssdev = &ddata->dssdev; dssdev->ops.hdmi = &tpd_hdmi_ops; dssdev->dev = &pdev->dev; dssdev->type = OMAP_DISPLAY_TYPE_HDMI; dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; dssdev->owner = THIS_MODULE; dssdev->port_num = 1; in = ddata->in; r = omapdss_register_output(dssdev); if (r) { dev_err(&pdev->dev, "Failed to register output\n"); goto err_reg; } return 0; err_reg: err_debounce: err_gpio: omap_dss_put_device(ddata->in); return r; }
__private_extern__ void configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info) { mig_reply_error_t * bufRequest = msg; uint32_t bufReply_q[MACH_MSG_BUFFER_SIZE/sizeof(uint32_t)]; mig_reply_error_t * bufReply = (mig_reply_error_t *)bufReply_q; static CFIndex bufSize = 0; mach_msg_return_t mr; int options; if (bufSize == 0) { // get max size for MiG reply buffers bufSize = _config_subsystem.maxsize; // check if our on-the-stack reply buffer will be big enough if (bufSize > sizeof(bufReply_q)) { SCLog(TRUE, LOG_NOTICE, CFSTR("configdCallback(): buffer size should be increased > %d"), _config_subsystem.maxsize); } } if (bufSize > sizeof(bufReply_q)) { bufReply = CFAllocatorAllocate(NULL, _config_subsystem.maxsize, 0); } bufReply->RetCode = 0; /* we have a request message */ (void) config_demux(&bufRequest->Head, &bufReply->Head); if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { if (bufReply->RetCode == MIG_NO_REPLY) { bufReply->Head.msgh_remote_port = MACH_PORT_NULL; } else if ((bufReply->RetCode != KERN_SUCCESS) && (bufRequest->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) { /* * destroy the request - but not the reply port */ bufRequest->Head.msgh_remote_port = MACH_PORT_NULL; mach_msg_destroy(&bufRequest->Head); } } if (bufReply->Head.msgh_remote_port != MACH_PORT_NULL) { /* * send reply. * * We don't want to block indefinitely because the client * isn't receiving messages from the reply port. * If we have a send-once right for the reply port, then * this isn't a concern because the send won't block. * If we have a send right, we need to use MACH_SEND_TIMEOUT. * To avoid falling off the kernel's fast RPC path unnecessarily, * we only supply MACH_SEND_TIMEOUT when absolutely necessary. */ options = MACH_SEND_MSG; if (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) != MACH_MSG_TYPE_MOVE_SEND_ONCE) { options |= MACH_SEND_TIMEOUT; } mr = mach_msg(&bufReply->Head, /* msg */ options, /* option */ bufReply->Head.msgh_size, /* send_size */ 0, /* rcv_size */ MACH_PORT_NULL, /* rcv_name */ MACH_MSG_TIMEOUT_NONE, /* timeout */ MACH_PORT_NULL); /* notify */ /* Has a message error occurred? */ switch (mr) { case MACH_SEND_INVALID_DEST: case MACH_SEND_TIMED_OUT: break; default : /* Includes success case. */ goto done; } } if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) { mach_msg_destroy(&bufReply->Head); } done : if (bufReply != (mig_reply_error_t *)bufReply_q) CFAllocatorDeallocate(NULL, bufReply); return; }