static int anx7816_i2c_remove(struct i2c_client *client) { struct anx7816_data *anx7816 = i2c_get_clientdata(client); int i = 0; for (i = 0; i < ARRAY_SIZE(slimport_device_attrs); i++) device_remove_file(&client->dev, &slimport_device_attrs[i]); free_irq(client->irq, anx7816); anx7816_free_gpio(anx7816); destroy_workqueue(anx7816->workqueue); wake_lock_destroy(&anx7816->slimport_lock); kfree(anx7816); return 0; }
static int anx7816_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct anx7816_data *anx7816; struct anx7816_platform_data *pdata; int ret = 0; int sbl_cable_type = 0; pr_info("%s %s start\n", LOG_TAG, __func__); #ifdef SP_REGISTER_SET_TEST val_SP_TX_LT_CTRL_REG0 = 0x19; val_SP_TX_LT_CTRL_REG10 = 0x00; val_SP_TX_LT_CTRL_REG11 = 0x00; val_SP_TX_LT_CTRL_REG2 = 0x36; val_SP_TX_LT_CTRL_REG12 = 0x00; val_SP_TX_LT_CTRL_REG1 = 0x26; val_SP_TX_LT_CTRL_REG6 = 0x3c; val_SP_TX_LT_CTRL_REG16 = 0x18; val_SP_TX_LT_CTRL_REG5 = 0x28; val_SP_TX_LT_CTRL_REG8 = 0x2F; val_SP_TX_LT_CTRL_REG15 = 0x10; val_SP_TX_LT_CTRL_REG18 = 0x1F; #endif if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { pr_err("%s: i2c bus does not support the anx7816\n", __func__); ret = -ENODEV; goto exit; } anx7816 = kzalloc(sizeof(struct anx7816_data), GFP_KERNEL); if (!anx7816) { pr_err("%s: failed to allocate driver data\n", __func__); ret = -ENOMEM; goto exit; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(struct anx7816_platform_data), GFP_KERNEL); if (!pdata) { pr_err("%s: Failed to allocate memory\n", __func__); return -ENOMEM; } client->dev.platform_data = pdata; /* device tree parsing function call */ ret = anx7816_parse_dt(&client->dev, pdata); if (ret != 0) /* if occurs error */ goto err0; anx7816->pdata = pdata; } else { anx7816->pdata = client->dev.platform_data; } /* to access global platform data */ g_pdata = anx7816->pdata; anx7816_client = client; mutex_init(&anx7816->lock); if (!anx7816->pdata) { ret = -EINVAL; goto err0; } ret = anx7816_init_gpio(anx7816); if (ret) { pr_err("%s: failed to initialize gpio\n", __func__); goto err0; } INIT_DELAYED_WORK(&anx7816->work, anx7816_work_func); /* INIT_DELAYED_WORK(&anx7816->dwc3_ref_clk_work, dwc3_ref_clk_work_func); */ anx7816->workqueue = create_singlethread_workqueue("anx7816_work"); if (anx7816->workqueue == NULL) { pr_err("%s: failed to create work queue\n", __func__); ret = -ENOMEM; goto err1; } anx7816->pdata->avdd_power(1); anx7816->pdata->dvdd_power(1); ret = anx7816_system_init(); if (ret) { pr_err("%s: failed to initialize anx7816\n", __func__); goto err2; } client->irq = gpio_to_irq(anx7816->pdata->gpio_cbl_det); if (client->irq < 0) { pr_err("%s : failed to get gpio irq\n", __func__); goto err2; } wake_lock_init(&anx7816->slimport_lock, WAKE_LOCK_SUSPEND, "slimport_wake_lock"); sbl_cable_type = anx7816_get_sbl_cable_type(); if ((lge_get_laf_mode() != LGE_LAF_MODE_LAF) && (sbl_cable_type != CBL_910K)) { ret = request_threaded_irq(client->irq, NULL, anx7816_cbl_det_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "anx7816", anx7816); if (ret < 0) { pr_err("%s : failed to request irq\n", __func__); goto err2; } ret = irq_set_irq_wake(client->irq, 1); if (ret < 0) { pr_err("%s : Request irq for cable detect", __func__); pr_err("interrupt wake set fail\n"); goto err3; } ret = enable_irq_wake(client->irq); if (ret < 0) { pr_err("%s : Enable irq for cable detect", __func__); pr_err("interrupt wake enable fail\n"); goto err3; } } else { pr_err("%s %s : %s, Disable cbl det irq!!\n", LOG_TAG, __func__, sbl_cable_type == CBL_910K ? "910K Cable Connected" : "Laf Mode"); } ret = create_sysfs_interfaces(&client->dev); if (ret < 0) { pr_err("%s : sysfs register failed", __func__); goto err3; } #ifdef CONFIG_SLIMPORT_DYNAMIC_HPD hdmi_slimport_ops = devm_kzalloc(&client->dev, sizeof(struct msm_hdmi_slimport_ops), GFP_KERNEL); if (!hdmi_slimport_ops) { pr_err("%s: alloc hdmi slimport ops failed\n", __func__); ret = -ENOMEM; goto err3; } if (anx7816->pdata->hdmi_pdev) { ret = msm_hdmi_register_slimport(anx7816->pdata->hdmi_pdev, hdmi_slimport_ops, anx7816); if (ret) { pr_err("%s: register with hdmi failed\n", __func__); ret = -EPROBE_DEFER; goto err3; } } #endif pr_info("%s %s end\n", LOG_TAG, __func__); goto exit; err3: free_irq(client->irq, anx7816); err2: destroy_workqueue(anx7816->workqueue); err1: anx7816_free_gpio(anx7816); err0: anx7816_client = NULL; kfree(anx7816); exit: return ret; }
/* int anx7816_get_sbl_cable_type(void) { int cable_type = 0; unsigned int *p_cable_type = (unsigned int *) (smem_get_entry(SMEM_ID_VENDOR1, &cable_smem_size)); if (p_cable_type) cable_type = *p_cable_type; else cable_type = 0; return cable_type; } */ static int anx7816_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct anx7816_data *anx7816; struct anx7816_platform_data *pdata; int ret = 0; //int sbl_cable_type = 0; pr_err("%s %s start\n", LOG_TAG, __func__); #ifdef SP_REGISTER_SET_TEST val_SP_TX_LT_CTRL_REG0 = 0x01; val_SP_TX_LT_CTRL_REG1 = 0x03; val_SP_TX_LT_CTRL_REG2 = 0x57; val_SP_TX_LT_CTRL_REG3 = 0x7f; val_SP_TX_LT_CTRL_REG4 = 0x71; val_SP_TX_LT_CTRL_REG5 = 0x6b; val_SP_TX_LT_CTRL_REG6 = 0x7f; val_SP_TX_LT_CTRL_REG7 = 0x73; val_SP_TX_LT_CTRL_REG8 = 0x7f; val_SP_TX_LT_CTRL_REG9 = 0x7f; val_SP_TX_LT_CTRL_REG10 = 0x00; val_SP_TX_LT_CTRL_REG11 = 0x00; val_SP_TX_LT_CTRL_REG12 = 0x02; val_SP_TX_LT_CTRL_REG13 = 0x00; val_SP_TX_LT_CTRL_REG14 = 0x0c; val_SP_TX_LT_CTRL_REG15 = 0x42; val_SP_TX_LT_CTRL_REG16 = 0x2f; val_SP_TX_LT_CTRL_REG17 = 0x3e; val_SP_TX_LT_CTRL_REG18 = 0x77; val_SP_TX_LT_CTRL_REG19 = 0x7e; #endif if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) { pr_err("%s: i2c bus does not support the anx7816\n", __func__); ret = -ENODEV; goto exit; } anx7816 = kzalloc(sizeof(struct anx7816_data), GFP_KERNEL); if (!anx7816) { pr_err("%s: failed to allocate driver data\n", __func__); ret = -ENOMEM; goto exit; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(struct anx7816_platform_data), GFP_KERNEL); if (!pdata) { pr_err("%s: Failed to allocate memory\n", __func__); ret = -ENOMEM; goto err0; } client->dev.platform_data = pdata; /* device tree parsing function call */ ret = anx7816_parse_dt(&client->dev, pdata); if (ret != 0) /* if occurs error */ goto err0; anx7816->pdata = pdata; } else { anx7816->pdata = client->dev.platform_data; } /* to access global platform data */ g_pdata = anx7816->pdata; anx7816_client = client; mutex_init(&anx7816->lock); if (!anx7816->pdata) { ret = -EINVAL; goto err0; } ret = anx7816_init_gpio(anx7816); if (ret) { pr_err("%s: failed to initialize gpio\n", __func__); goto err0; } INIT_DELAYED_WORK(&anx7816->work, anx7816_work_func); /* INIT_DELAYED_WORK(&anx7816->dwc3_ref_clk_work, dwc3_ref_clk_work_func); */ anx7816->workqueue = create_singlethread_workqueue("anx7816_work"); if (anx7816->workqueue == NULL) { pr_err("%s: failed to create work queue\n", __func__); ret = -ENOMEM; goto err1; } //anx7816->pdata->avdd_power(1); //anx7816->pdata->dvdd_power(1); ret = anx7816_system_init(); if (ret) { pr_err("%s: failed to initialize anx7816\n", __func__); goto err2; } client->irq = gpio_to_irq(anx7816->pdata->gpio_cbl_det); if (client->irq < 0) { pr_err("%s : failed to get gpio irq\n", __func__); goto err2; } wake_lock_init(&anx7816->slimport_lock, WAKE_LOCK_SUSPEND, "slimport_wake_lock"); #if 0 sbl_cable_type = anx7816_get_sbl_cable_type(); if ((lge_get_laf_mode() != LGE_LAF_MODE_LAF) && (sbl_cable_type != CBL_910K)) { #else if ((lge_get_boot_mode() != LGE_BOOT_MODE_QEM_910K) && (lge_get_boot_mode() != LGE_BOOT_MODE_PIF_910K)) { #endif ret = request_threaded_irq(client->irq, NULL, anx7816_cbl_det_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "anx7816", anx7816); if (ret < 0) { pr_err("%s : failed to request irq\n", __func__); goto err2; } ret = irq_set_irq_wake(client->irq, 1); if (ret < 0) { pr_err("%s : Request irq for cable detect", __func__); pr_err("interrupt wake set fail\n"); goto err3; } ret = enable_irq_wake(client->irq); if (ret < 0) { pr_err("%s : Enable irq for cable detect", __func__); pr_err("interrupt wake enable fail\n"); goto err3; } } else { #if 0 pr_err("%s %s : %s, Disable cbl det irq!!\n", LOG_TAG, __func__, sbl_cable_type == CBL_910K ? "910K Cable Connected" : "Laf Mode"); #else pr_err("%s %s: 910K Cable Connected. Disable cbl det irq!!\n", LOG_TAG, __func__); #endif } ret = create_sysfs_interfaces(&client->dev); if (ret < 0) { pr_err("%s : sysfs register failed", __func__); goto err3; } #ifdef CONFIG_SLIMPORT_DYNAMIC_HPD hdmi_slimport_ops = devm_kzalloc(&client->dev, sizeof(struct msm_hdmi_slimport_ops), GFP_KERNEL); if (!hdmi_slimport_ops) { pr_err("%s: alloc hdmi slimport ops failed\n", __func__); ret = -ENOMEM; goto err3; } if (anx7816->pdata->hdmi_pdev) { ret = msm_hdmi_register_slimport(anx7816->pdata->hdmi_pdev, hdmi_slimport_ops, anx7816); if (ret) { pr_err("%s: register with hdmi failed\n", __func__); ret = -EPROBE_DEFER; goto err3; } } #endif pr_info("%s %s end\n", LOG_TAG, __func__); goto exit; err3: free_irq(client->irq, anx7816); err2: destroy_workqueue(anx7816->workqueue); err1: anx7816_free_gpio(anx7816); err0: anx7816_client = NULL; kfree(anx7816); exit: return ret; } static int anx7816_i2c_remove(struct i2c_client *client) { struct anx7816_data *anx7816 = i2c_get_clientdata(client); int i = 0; for (i = 0; i < ARRAY_SIZE(slimport_device_attrs); i++) device_remove_file(&client->dev, &slimport_device_attrs[i]); pr_err("anx7816_i2c_remove\n"); sp_tx_clean_state_machine(); destroy_workqueue(anx7816->workqueue); sp_tx_hardware_powerdown(); free_irq(client->irq, anx7816); anx7816_free_gpio(anx7816); wake_lock_destroy(&anx7816->slimport_lock); kfree(anx7816); return 0; } bool is_slimport_vga(void) { return ((sp_tx_cur_cable_type() == DWN_STRM_IS_VGA_9832) || (sp_tx_cur_cable_type() == DWN_STRM_IS_ANALOG)) ? 1 : 0; } /* 0x01: hdmi device is attached 0x02: DP device is attached 0x03: Old VGA device is attached // RX_VGA_9832 0x04: new combo VGA device is attached // RX_VGA_GEN 0x00: unknow device */ EXPORT_SYMBOL(is_slimport_vga); bool is_slimport_dp(void) { return (sp_tx_cur_cable_type() == DWN_STRM_IS_DIGITAL) ? TRUE : FALSE; } EXPORT_SYMBOL(is_slimport_dp); unchar sp_get_link_bw(void) { return sp_tx_cur_bw(); } EXPORT_SYMBOL(sp_get_link_bw); void sp_set_link_bw(unchar link_bw) { sp_tx_set_bw(link_bw); }