static int hdmi_streamoff(struct hdmi_device *hdev) { struct device *dev = hdev->dev; dev_dbg(dev, "%s\n", __func__); if (hdev->hdcp_info.hdcp_enable && hdev->hdcp_info.hdcp_start) hdcp_stop(hdev); hdmi_audio_enable(hdev, 0); hdmi_enable(hdev, 0); hdmi_tg_enable(hdev, 0); hdev->streaming = HDMI_STOP; /* change the HPD interrupt: Internal -> External */ disable_irq(hdev->int_irq); cancel_work_sync(&hdev->hpd_work); hdmi_reg_set_ext_hpd(hdev); enable_irq(hdev->ext_irq); dev_info(hdev->dev, "HDMI interrupt changed to external\n"); hdmi_dumpregs(hdev, "streamoff"); return 0; }
static int Colorado_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; struct hdmi *hdmi = NULL; struct anx7805_pdata *anx = NULL; D("##########Colorado_i2c_probe##############\n"); memcpy(&g_client, &client, sizeof(client)); Colorado_init_gpio(); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C/*I2C_FUNC_SMBUS_I2C_BLOCK*/)) { dev_err(&client->dev, "i2c bus does not support the Colorado\n"); err = -ENODEV; goto exit_kfree; } anx = kzalloc(sizeof(struct anx7805_pdata), GFP_KERNEL); if(!anx) { dev_err(&client->dev, "no memory for state\n"); goto err_kzalloc_anx; } anx->client = client; anx->dev.detect = 0; // Register HDMI device hdmi = hdmi_register(&client->dev, &anx7805_ops); if(hdmi == NULL) { dev_err(&client->dev, "fail to register hdmi\n"); goto err_hdmi_register; } hdmi_set_privdata(hdmi, anx); anx->dev.hdmi = hdmi; i2c_set_clientdata(client, anx); err = Colorado_System_Init(); if (err) goto exit_kfree; HDMI_task(hdmi); queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 1); hdmi_enable(hdmi); dev_info(&client->dev, "anx7150 probe ok\n"); return 0; exit_kfree: hdmi_unregister(hdmi); err_hdmi_register: kfree(anx); anx = NULL; err_kzalloc_anx: hdmi = NULL; dev_err(&client->dev, "anx7805 probe error\n"); return err; }
static int hdmi_streamoff(struct hdmi_device *hdev) { struct device *dev = hdev->dev; struct hdmi_resources *res = &hdev->res; dev_dbg(dev, "%s\n", __func__); if (hdev->hdcp_info.hdcp_enable) hdcp_stop(hdev); hdmi_audio_enable(hdev, 0); hdmi_enable(hdev, 0); hdmi_tg_enable(hdev, 0); /* pixel(vpll) clock is used for HDMI in config mode */ clk_disable(res->sclk_hdmi); clk_set_parent(res->sclk_hdmi, res->sclk_pixel); clk_enable(res->sclk_hdmi); v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); hdev->streaming = 0; hdmi_dumpregs(hdev, "streamoff"); return 0; }
static int hdmi_streamon(struct hdmi_device *hdev) { struct device *dev = hdev->dev; int ret; u32 val0, val1, val2; dev_dbg(dev, "%s\n", __func__); /* 3D test */ hdmi_set_infoframe(hdev); /* set packets for audio */ hdmi_set_packets(hdev); /* init audio */ #if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S) hdmi_reg_i2s_audio_init(hdev); #elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF) hdmi_reg_spdif_audio_init(hdev); #endif /* enbale HDMI audio */ if (hdev->audio_enable) hdmi_audio_enable(hdev, 1); hdmi_set_dvi_mode(hdev); /* controls the pixel value limitation */ hdmi_reg_set_limits(hdev); /* enable HDMI and timing generator */ hdmi_enable(hdev, 1); hdmi_tg_enable(hdev, 1); hdev->streaming = HDMI_STREAMING; /* change the HPD interrupt: External -> Internal */ disable_irq(hdev->ext_irq); cancel_delayed_work_sync(&hdev->hpd_work_ext); hdmi_reg_set_int_hpd(hdev); enable_irq(hdev->int_irq); dev_info(hdev->dev, "HDMI interrupt changed to internal\n"); /* start HDCP if enabled */ if (hdev->hdcp_info.hdcp_enable) { ret = hdcp_start(hdev); if (ret) return ret; } val0 = hdmi_read(hdev, HDMI_ACR_MCTS0); val1 = hdmi_read(hdev, HDMI_ACR_MCTS1); val2 = hdmi_read(hdev, HDMI_ACR_MCTS2); dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0); dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1); dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2); hdmi_dumpregs(hdev, "streamon"); return 0; }
static void external_display_enable(unsigned long param) { EXTD_DEV_ID device_id = EXTD_DEV_ID(param); int enable = EXTD_DEV_PARAM(param); switch(device_id) { case DEV_MHL: hdmi_enable(enable); break; case DEV_WFD: /*enable or diable wifi display*/ break; default: break; } }
status_t HDMIDaemon::readyToRun() { if ((mFrameworkSock = android_get_control_socket(HDMI_SOCKET_NAME)) < 0) { ALOGE("Obtaining file descriptor socket '%s' failed: %s", HDMI_SOCKET_NAME, strerror(errno)); return -1; } if (listen(mFrameworkSock, 4) < 0) { ALOGE("Unable to listen on fd '%d' for socket '%s': %s", mFrameworkSock, HDMI_SOCKET_NAME, strerror(errno)); return -1; } mUeventSock = hdmi_init(0); hdmi_enable(); ALOGD("readyToRun: success"); return NO_ERROR; }
static int hdmi_streamoff(struct hdmi_device *hdev) { struct device *dev = hdev->dev; dev_dbg(dev, "%s\n", __func__); hdmi_reg_set_ext_hpd(hdev); // if (edid_supports_hdmi(hdev)) { #if 1 if (hdev->hdcp_info.hdcp_enable && hdev->hdcp_info.hdcp_start) hdcp_stop(hdev); #endif // } hdmi_audio_enable(hdev, 0); hdmi_enable(hdev, 0); hdmi_tg_enable(hdev, 0); hdev->streaming = HDMI_STOP; hdmi_dumpregs(hdev, "streamoff"); return 0; }
static int hdmi_streamon(struct hdmi_device *hdev) { struct device *dev = hdev->dev; int ret; u32 val0, val1, val2; dev_dbg(dev, "%s\n", __func__); /* 3D test */ hdmi_set_infoframe(hdev); /* set packets for audio */ hdmi_set_packets(hdev); /* init audio */ #if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S) //printk("=============================> HDMI IIS\n"); hdmi_reg_i2s_audio_init(hdev); #elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF) hdmi_reg_spdif_audio_init(hdev); #endif /* enbale HDMI audio */ if (hdev->audio_enable) { //printk("<+++++++++++++++++++++++++++++++++++++++++++ HDMI ENABLE\n"); hdmi_audio_enable(hdev, 1); //printk("<+++++++++++++++++++++++++++++++++++++++++++ HDMI ENABLE\n"); } hdmi_set_dvi_mode(hdev); /* controls the pixel value limitation */ hdmi_reg_set_limits(hdev); /* enable HDMI and timing generator */ hdmi_enable(hdev, 1); hdmi_tg_enable(hdev, 1); hdmi_reg_set_int_hpd(hdev); hdev->streaming = HDMI_STREAMING; // if (edid_supports_hdmi(hdev)) { #if 1 /* start HDCP if enabled */ if (hdev->hdcp_info.hdcp_enable) { ret = hdcp_start(hdev); if (ret) return ret; } #endif // } val0 = hdmi_read(hdev, HDMI_ACR_MCTS0); val1 = hdmi_read(hdev, HDMI_ACR_MCTS1); val2 = hdmi_read(hdev, HDMI_ACR_MCTS2); dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0); dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1); dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2); hdmi_dumpregs(hdev, "streamon"); return 0; }
static int hdmi_streamon(struct hdmi_device *hdev) { struct device *dev = hdev->dev; struct hdmi_resources *res = &hdev->res; int ret, tries; u32 val0, val1, val2; dev_dbg(dev, "%s\n", __func__); hdev->streaming = 1; ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1); if (ret) return ret; /* waiting for HDMIPHY's PLL to get to steady state */ for (tries = 100; tries; --tries) { if (is_hdmiphy_ready(hdev)) break; mdelay(1); } /* steady state not achieved */ if (tries == 0) { dev_err(dev, "hdmiphy's pll could not reach steady state.\n"); v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0); hdmi_dumpregs(hdev, "s_stream"); return -EIO; } /* hdmiphy clock is used for HDMI in streaming mode */ clk_disable(res->sclk_hdmi); clk_set_parent(res->sclk_hdmi, res->sclk_hdmiphy); clk_enable(res->sclk_hdmi); /* 3D test */ hdmi_set_infoframe(hdev); /* set packets for audio */ hdmi_set_packets(hdev); /* init audio */ #if defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_I2S) hdmi_reg_i2s_audio_init(hdev); #elif defined(CONFIG_VIDEO_EXYNOS_HDMI_AUDIO_SPDIF) hdmi_reg_spdif_audio_init(hdev); #endif /* enbale HDMI audio */ if (hdev->audio_enable) hdmi_audio_enable(hdev, 1); hdmi_set_dvi_mode(hdev); /* enable HDMI and timing generator */ hdmi_enable(hdev, 1); hdmi_tg_enable(hdev, 1); mdelay(5); val0 = hdmi_read(hdev, HDMI_ACR_MCTS0); val1 = hdmi_read(hdev, HDMI_ACR_MCTS1); val2 = hdmi_read(hdev, HDMI_ACR_MCTS2); dev_dbg(dev, "HDMI_ACR_MCTS0 : 0x%08x\n", val0); dev_dbg(dev, "HDMI_ACR_MCTS1 : 0x%08x\n", val1); dev_dbg(dev, "HDMI_ACR_MCTS2 : 0x%08x\n", val2); /* start HDCP if enabled */ if (hdev->hdcp_info.hdcp_enable) { ret = hdcp_start(hdev); if (ret) return ret; } hdmi_dumpregs(hdev, "streamon"); return 0; }
int HDMI_task(struct hdmi *hdmi) { int rc, state, state_last, hpd, trytimes; // state = g_state; // hdmi_sys_show_state(hdmi, state); /* Process parametre changed */ state = hdmi_sys_change(hdmi); /* Initialize hdmi chips when system start.*/ if(state == HDMI_UNKNOWN) { rc = hdmi_sys_init(hdmi); state = WAIT_HOTPLUG; } if(!hdmi->enable) goto exit; /* Detect hdmi status */ state = hdmi_sys_detect_status(hdmi, state); /* Process HDMI status machine */ rc = 0; trytimes = 0; do { state_last = state; switch(state) { case HDMI_INITIAL: rc = hdmi_sys_init(hdmi); if(rc == HDMI_ERROR_SUCESS) { hdmi->rate = 0; state = WAIT_HOTPLUG; } else hdmi->rate = HDMI_TASK_INTERVAL; break; case WAIT_HOTPLUG: hdmi->rate = HDMI_TASK_INTERVAL; if(hdmi->hpd_status > HDMI_RECEIVER_REMOVE) { #ifdef HDMI_DEBUG_TIME hdmi_time_start = jiffies; #endif if(hdmi->ops->insert) { rc = hdmi->ops->insert(hdmi); } if(rc == HDMI_ERROR_SUCESS) { state = READ_PARSE_EDID; } else hdmi->rate = HDMI_TASK_INTERVAL; } break; case READ_PARSE_EDID: rc = hdmi_sys_parse_edid(hdmi); #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI EDID parse cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif if(rc == HDMI_ERROR_SUCESS) { hdmi->rate = 0; state = WAIT_RX_SENSE; hdmi_sys_send_uevent(hdmi, KOBJ_ADD); } else hdmi->rate = HDMI_TASK_INTERVAL; break; case WAIT_RX_SENSE: if(hdmi->ops->detect_sink) { rc = hdmi->ops->detect_sink(hdmi, &hpd); hdmi->hpd_status = hpd; if(hpd == HDMI_RECEIVER_ACTIVE) { //Only when HDMI receiver is actived, //HDMI communication is successful. state = WAIT_HDMI_ENABLE; hdmi->rate = 0; } else { rc = HDMI_ERROR_FALSE; hdmi->rate = HDMI_TASK_INTERVAL; } } else { hdmi->hpd_status = HDMI_RECEIVER_ACTIVE; hdmi->rate = 0; state = WAIT_HDMI_ENABLE; if(hdmi->auto_switch) hdmi_enable(hdmi); } #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI sink enable cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif break; case WAIT_HDMI_ENABLE: if(hdmi->config_set.display_on == HDMI_DISPLAY_OFF) hdmi->rate = HDMI_TASK_INTERVAL; else state = SYSTEM_CONFIG; break; case SYSTEM_CONFIG: if(hdmi->auto_switch) { rk_display_device_disable_other(hdmi->ddev); g_lcdcstatus = 1; } if(hdmi->auto_config) hdmi->config_set.resolution = ext_hdmi_find_best_mode(hdmi, 0); else hdmi->config_set.resolution = ext_hdmi_find_best_mode(hdmi, hdmi->config_set.resolution); rc = ext_hdmi_switch_fb(hdmi, 1); #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI configure LCD cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif if(rc == HDMI_ERROR_SUCESS) { state = CONFIG_VIDEO; hdmi->rate = 0; } else hdmi->rate = HDMI_TASK_INTERVAL; break; case CONFIG_VIDEO: { hdmi->config_real.display_on = HDMI_DISABLE; if(hdmi->edid.is_hdmi) { if(hdmi->edid.ycbcr444) hdmi->config_set.color = HDMI_VIDEO_YCbCr444; else if(hdmi->edid.ycbcr422) hdmi->config_set.color = HDMI_VIDEO_YCbCr422; else hdmi->config_set.color = HDMI_VIDEO_RGB; } else hdmi->config_set.color = HDMI_VIDEO_RGB; if(hdmi->config_set.color > HDMI_VIDEO_RGB && (!hdmi->support_r2y)) hdmi->config_set.color = HDMI_VIDEO_RGB; rc = hdmi->ops->config_video(hdmi, hdmi->config_set.resolution, HDMI_VIDEO_RGB, /*HDMI_VIDEO_RGB*/hdmi->config_set.color); #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI configure VIDEO cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif } if(rc == HDMI_ERROR_SUCESS) { hdmi->rate = 0; if(hdmi->edid.is_hdmi) state = CONFIG_AUDIO; else state = PLAY_BACK; } else hdmi->rate = HDMI_TASK_INTERVAL; break; case CONFIG_AUDIO: rc = hdmi->ops->config_audio(hdmi, &(hdmi->config_set.audio)); #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI configure Audio cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif if(rc == HDMI_ERROR_SUCESS) { hdmi->rate = 0; state = PLAY_BACK; } else hdmi->rate = HDMI_TASK_INTERVAL; break; #if 0 case HDCP_AUTHENTICATION: if(hdmi->ops->config_hdcp) { rc = hdmi->ops->config_hdcp(hdmi, hdmi->config_set.hdcp_on); #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI configure HDCP cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif } if(rc == HDMI_ERROR_SUCESS) { hdmi->rate = 0; state = PLAY_BACK; } else hdmi->rate = HDMI_TASK_INTERVAL; break; #endif case PLAY_BACK: // if(hdmi->config_real.display_on != hdmi->config_set.display_on) if( memcmp(&(hdmi->config_real), &(hdmi->config_set), sizeof(struct hdmi_configs)) ) { if(hdmi->config_set.display_on == HDMI_DISPLAY_ON) { if(hdmi->ops->config_hdcp) rc = hdmi->ops->config_hdcp(hdmi, hdmi->config_set.hdcp_on); rc |= hdmi->ops->enable(hdmi, HDMI_ENABLE); } else rc = hdmi->ops->enable(hdmi, HDMI_DISABLE); if(rc == HDMI_ERROR_SUCESS) { #ifdef HDMI_DEBUG_TIME hdmi_time_end = jiffies; if(hdmi_time_end > hdmi_time_start) hdmi_time_end -= hdmi_time_start; else hdmi_time_end += 0xFFFFFFFF - hdmi_time_start; dev_printk(KERN_INFO, hdmi->dev, "HDMI configuration cost %u ms\n", jiffies_to_msecs(hdmi_time_end)); #endif memcpy(&(hdmi->config_real), &(hdmi->config_set), sizeof(struct hdmi_configs)); } if(hdmi->config_set.display_on == HDMI_DISABLE) state = WAIT_HDMI_ENABLE; } if(hdmi->wait == 1) { complete(&hdmi->complete); hdmi->wait = 0; } hdmi->rate = HDMI_TASK_INTERVAL; break; default: state = HDMI_INITIAL; hdmi->rate = HDMI_TASK_INTERVAL; break; } if(rc != HDMI_ERROR_SUCESS) { trytimes++; msleep(10); } if(state != state_last) { trytimes = 0; hdmi_sys_show_state(hdmi, state); } }while((state != state_last || (rc != HDMI_ERROR_SUCESS) ) && trytimes < HDMI_MAX_TRY_TIMES); if(trytimes == HDMI_MAX_TRY_TIMES) { if(hdmi->hpd_status) { if(state == CONFIG_AUDIO) state = HDCP_AUTHENTICATION; else if(state > WAIT_RX_SENSE) { hdmi_sys_unplug(hdmi); if(hdmi->auto_switch && g_lcdcstatus) { rk_display_device_enable_other(hdmi->ddev); g_lcdcstatus = 0; } state = HDMI_UNKNOWN; } } } exit: if(state != g_state) g_state = state; return 0; }
int hdmi_entry(struct ftm_param *param, void *priv) { bool exit = false; hdmi_module *hdmi = (hdmi_module *)priv; struct itemview *iv; LOGD(TAG "hdmi_entry\n"); /* show text view */ if (!hdmi->itm_view) { iv = ui_new_itemview(); if (!iv) { LOGD(TAG "No memory for item view"); return -1; } hdmi->itm_view = iv; } iv = hdmi->itm_view; //init item view memset(&hdmi->info[0], 0, sizeof(hdmi->info)); memset(&hdmi->info[0], '\n', 10); init_text(&hdmi->title, param->name, COLOR_YELLOW); init_text(&hdmi->text, &hdmi->info[0], COLOR_YELLOW); iv->set_title(iv, &hdmi->title); iv->set_items(iv, hdmi_item, 0); iv->set_text(iv, &hdmi->text); //iv->redraw(iv); if(hdmi_enable()) { LOGD(TAG "hdmi test fail\n"); //hdmi->text.color = COLOR_RED; sprintf(hdmi->info, "HDMI "uistr_fail"\n"); } else { LOGD(TAG "hdmi test pass\n"); //hdmi->text.color = COLOR_GREEN; sprintf(hdmi->info, "HDMI "uistr_pass"\n"); } while(!exit) { switch(iv->run(iv, NULL)) { case ITEM_PASS: hdmi->module->test_result = FTM_TEST_PASS; exit = true; break; case ITEM_FAIL: hdmi->module->test_result = FTM_TEST_FAIL; exit = true; break; case -1: exit = true; break; default: break; } } //hdmi_disable(); return 0; }
static int rk610_hdmi_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id) { int rc = 0; struct hdmi *hdmi = NULL; struct rkdisplay_platform_data *hdmi_data = client->dev.platform_data; rk610_hdmi = kzalloc(sizeof(struct rk610_hdmi_pdata), GFP_KERNEL); if(!rk610_hdmi) { dev_err(&client->dev, "no memory for state\n"); goto err_kzalloc_rk610_hdmi; } rk610_hdmi->client = client; if(hdmi_data) hdmi = hdmi_register(&client->dev, &rk610_hdmi_ops, hdmi_data->video_source, hdmi_data->property); else hdmi = hdmi_register(&client->dev, &rk610_hdmi_ops, DISPLAY_SOURCE_LCDC0, DISPLAY_MAIN); if(hdmi == NULL) { dev_err(&client->dev, "fail to register hdmi\n"); goto err_hdmi_register; } hdmi->support_r2y = 1; rk610_hdmi->hdmi = hdmi; hdmi_set_privdata(hdmi, rk610_hdmi); i2c_set_clientdata(client, rk610_hdmi); { #ifdef HDMI_USE_IRQ // hdmi_changed(hdmi, 0); INIT_WORK(&rk610_hdmi->irq_work, rk610_irq_work_func); if((rc = gpio_request(client->irq, "hdmi gpio")) < 0) { dev_err(&client->dev, "fail to request gpio %d\n", client->irq); goto err_request_gpio; } rk610_hdmi->irq = gpio_to_irq(client->irq); rk610_hdmi->gpio = client->irq; gpio_pull_updown(client->irq,GPIOPullUp); gpio_direction_input(client->irq); if((rc = request_irq(rk610_hdmi->irq, rk610_irq,IRQF_TRIGGER_RISING,NULL,hdmi)) < 0) { dev_err(&client->dev, "fail to request hdmi irq\n"); goto err_request_irq; } #else HDMI_task(hdmi); queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 200); #endif hdmi_enable(hdmi); dev_info(&client->dev, "rk610 hdmi i2c probe ok\n"); } return 0; err_request_irq: gpio_free(client->irq); err_request_gpio: hdmi_unregister(hdmi); err_hdmi_register: kfree(rk610_hdmi); rk610_hdmi = NULL; err_kzalloc_rk610_hdmi: hdmi = NULL; dev_err(&client->dev, "rk610 hdmi probe error\n"); return rc; }
static int anx7150_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id) { int rc = 0; struct hdmi *hdmi = NULL; struct anx7150_pdata *anx = NULL; struct rkdisplay_platform_data *hdmi_data = client->dev.platform_data; anx = kzalloc(sizeof(struct anx7150_pdata), GFP_KERNEL); if(!anx) { dev_err(&client->dev, "no memory for state\n"); goto err_kzalloc_anx; } anx->client = client; anx->dev.anx7150_detect = 0; anx->init = 1; // Register HDMI device if(hdmi_data) { anx->io_pwr_pin = hdmi_data->io_pwr_pin; anx->io_rst_pin = hdmi_data->io_reset_pin; hdmi = hdmi_register(&client->dev, &anx7150_ops, hdmi_data->video_source, hdmi_data->property); } else { anx->io_pwr_pin = INVALID_GPIO; anx->io_rst_pin = INVALID_GPIO; hdmi = hdmi_register(&client->dev, &anx7150_ops, DISPLAY_SOURCE_LCDC0, DISPLAY_MAIN); } if(hdmi == NULL) { dev_err(&client->dev, "fail to register hdmi\n"); goto err_hdmi_register; } // Set HDMI private data hdmi_set_privdata(hdmi, anx); anx->dev.hdmi = hdmi; i2c_set_clientdata(client, anx); //Power on anx7150 if(anx->io_pwr_pin != INVALID_GPIO) { rc = gpio_request(anx->io_pwr_pin, NULL); if(rc) { gpio_free(anx->io_pwr_pin); printk(KERN_ERR "request anx7150 power control gpio error\n "); goto err_hdmi_register; } else gpio_direction_output(anx->io_pwr_pin, GPIO_HIGH); } anx->dev.anx7150_detect = ANX7150_hw_detect_device(anx->client); if(anx->dev.anx7150_detect) { HDMI_task(hdmi); #ifdef HDMI_USE_IRQ hdmi_changed(hdmi, 1); if((rc = gpio_request(client->irq, "hdmi gpio")) < 0) { dev_err(&client->dev, "fail to request gpio %d\n", client->irq); goto err_request_gpio; } anx->irq = gpio_to_irq(client->irq); anx->io_irq_pin = client->irq; gpio_pull_updown(client->irq,GPIOPullDown); gpio_direction_input(client->irq); #ifndef CONFIG_ANX7150_IRQ_USE_CHIP anx->init = IRQF_TRIGGER_RISING; if((rc = request_irq(anx->irq, anx7150_detect_irq,IRQF_TRIGGER_RISING,NULL,hdmi)) <0) #else if((rc = request_irq(anx->irq, anx7150_detect_irq,IRQF_TRIGGER_FALLING,NULL,hdmi)) <0) #endif { dev_err(&client->dev, "fail to request hdmi irq\n"); goto err_request_irq; } #else queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 1); #endif hdmi_enable(hdmi); dev_info(&client->dev, "anx7150 probe ok\n"); } else goto err_request_irq; return 0; err_request_irq: gpio_free(client->irq); err_request_gpio: hdmi_unregister(hdmi); err_hdmi_register: kfree(anx); anx = NULL; err_kzalloc_anx: hdmi = NULL; dev_err(&client->dev, "anx7150 probe error\n"); return rc; }