static int dsm_register_extern_client(struct dsm_extern_client* ext_client)
{
    static int ext_client_cnt = 0;

    ext_dev[ext_client_cnt].buff_size = ext_client->buf_size;
    ext_dev[ext_client_cnt].name = ext_client->client_name;

    if (0 >= ext_dev[ext_client_cnt].buff_size || NULL == ext_dev[ext_client_cnt].name
            || ext_client_cnt >= EXTERN_DSM_CLIENT_MAX) {
        DSM_LOG_ERR("[dsm_register_extern_client]client name or buf_size is fault."
                    "don't register!\n");
        return -ENOENT;
    } else if (NULL != dsm_find_client(ext_dev[ext_client_cnt].name)) {
        DSM_LOG_ERR("[dsm_register_extern_client]register %s has exist, dont register again!\n",
                    ext_dev[ext_client_cnt].name);
        return -EEXIST;
    }

    ext_dsm_client[ext_client_cnt] = dsm_register_client(&ext_dev[ext_client_cnt]);
    if (!ext_dsm_client[ext_client_cnt]) {
        DSM_LOG_ERR("[dsm_register_extern_client]register %s failed!\n",
                    ext_dev[ext_client_cnt].name);
        return -ENOMEM;
    }

    ext_client_cnt++;
    return 0;
}
static int cpu_buck_probe(struct platform_device *pdev)
{
    struct device_node* np;
    struct cpu_buck_device_info* di;

    np = pdev->dev.of_node;
    if(NULL == np)
    {
        hwlog_err("np is NULL\n");
        return -1;
    }
    di = kzalloc(sizeof(*di), GFP_KERNEL);
    if (!di)
    {
        hwlog_err("di is NULL\n");
        return -ENOMEM;
    }
    if (!cpu_buck_client)
    {
        cpu_buck_client = dsm_register_client(&dsm_cpu_buck);
    }
    if (NULL == cpu_buck_client)
    {
        hwlog_err("cpu_buck register dsm fail\n");
        return -1;
    }
    INIT_DELAYED_WORK(&di->cpu_buck_delayed_work, cpu_buck_work);
    schedule_delayed_work(&di->cpu_buck_delayed_work, 10);
    hwlog_info("cpu_buck probe ok!\n");
    return 0;
}
static int  inputhub_mcu_init(void)
{
    int ret;
    init_completion(&send_complete);
#ifdef CONFIG_IOM3_RECOVERY
    atomic_set(&iom3_rec_state, IOM3_RECOVERY_UNINIT);
    iom3_rec_wq = create_singlethread_workqueue("iom3_rec_wq");
    if (!iom3_rec_wq)
    {
        hwlog_err("--------------------> faild in create iom3 wq in %s!\n", __func__);
        return -1;
    }
    INIT_DELAYED_WORK(&iom3_rec_work, iom3_recovery_work);
    init_completion(&iom3_rec_done);
    wake_lock_init(&iom3_rec_wl, WAKE_LOCK_SUSPEND, "iom3_rec_wl");
#endif
    ret = inputhub_route_init();
    inputhub_mcu_connect();
    if (NULL == mbox) {
        hwlog_err("--------------------> faild to get mailbox in %s!\n", __func__);
        return -1;
    } else {
        hwlog_info("--------------------> succeed to get mailbox in %s!\n", __func__);
    }
    boot_iom3();
    setSensorMcuMode(1);
    shb_dclient = dsm_register_client(&dsm_sensorhub);
    hwlog_info("----%s--->\n",__func__);
    return ret;
}
예제 #4
0
static int max98925_i2c_probe(struct i2c_client *i2c_l,
			     const struct i2c_device_id *id)
{
	int ret;

	pr_err("%s: enter, device '%s'\n", __func__, id->name);

	max98925_data = kzalloc(sizeof(struct max98925_priv), GFP_KERNEL);
	if (max98925_data == NULL)
		return -ENOMEM;

	max98925_data->devtype = id->driver_data;
	max98925_data->control_data = i2c_l;
	//max98925_data->pdata = i2c_l->dev.platform_data;

	max98925_data->regmapL = regmap_init_i2c(i2c_l, &max98925_regmap);
	if (IS_ERR(max98925_data->regmapL)) {
		ret = PTR_ERR(max98925_data->regmapL);
		dev_err(&i2c_l->dev, "Failed to allocate regmapL: %d\n", ret);
		goto err_out;
	}
/*
	ret = of_property_read_u32(i2c_l->dev.of_node,
				"irq-gpio", &max98925_data->irq_gpio);
	if (ret) {
		dev_err(&i2c_l->dev, "DT has no property named irq_gpio\n");
		goto err_out;
	}

	ret = request_threaded_irq(gpio_to_irq(max98925_data->irq_gpio), NULL, max98925_irq_handler,
			IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "MAX98925", max98925_data);
	if (ret < 0) {
		dev_err(&i2c_l->dev, "Failed to register IRQ for GPIO %d, error = %d\n",
			max98925_data->irq_gpio, ret);
		goto err_out;
	}
*/
	ret = sysfs_create_file(&i2c_l->dev.kobj, &dev_attr_register_list.attr);
	ret |= misc_register(&max98925_ctrl_miscdev);

	pr_info("%s: ret %d\n", __func__, ret);

	if(!max98925_dclient){
		max98925_dclient = dsm_register_client(&dsm_maxim_smartpa);
	}
err_out:

	if (ret < 0) {
		if (max98925_data->regmapL)
			regmap_exit(max98925_data->regmapL);
		kfree(max98925_data);
	}

	return ret;
}
static int __init sensor_input_info_init(void)
{
	int ret = 0;
	printk(KERN_INFO"[%s] ++", __func__);

#if defined (CONFIG_HUAWEI_DSM)
	 if(!gsensor_dclient)
	 {
      gsensor_dclient = dsm_register_client(&dsm_gsensor);
      }
	 if(!als_ps_dclient)
	 {
	     als_ps_dclient = dsm_register_client(&dsm_als_ps);
	 }

	  if (!compass_dclient)
	  {
	       compass_dclient = dsm_register_client(&dsm_compass);
           }
#endif
	ret = platform_device_register(&sensor_input_info);
	if (ret){
		pr_err("%s: platform_device_register failed, ret:%d.\n",
				__func__, ret);
		goto REGISTER_ERR;
	}

	ret = sysfs_create_group(&sensor_input_info.dev.kobj, &sensor_input);
	if (ret) {
		pr_err("sensor_input_info_init sysfs_create_group error ret =%d", ret);
		goto SYSFS_CREATE_CGOUP_ERR;
	}
	printk(KERN_INFO"[%s] --", __func__);

	return 0;
SYSFS_CREATE_CGOUP_ERR:
	platform_device_unregister(&sensor_input_info);
REGISTER_ERR:
	return ret;

}
/**
 * func - lis_gsensor_dsm_init
 *
 * 	register dsm_client, and set acceld as dsm_client driver_data.
 *
 */
static int lis_gsensor_dsm_init(struct lis3dh_acc_data  *acceld)
{

	lis3dh_gs_dclient = dsm_register_client(&dsm_gs_lis_i2c);
	if (!lis3dh_gs_dclient) {
		pr_err("[lis3dh_err]register dsm lis3dh_gs_dclient failed!\n");
		return -ENOMEM;
	}

	lis3dh_gs_dclient->driver_data = acceld;
	acceld->gsensor_dclient = lis3dh_gs_dclient;

	return 0;
}
int audio_dsm_register(void)
{
    if (NULL != audio_dclient) 
    {
        return 0;
    }

    audio_dclient = dsm_register_client(&audio_dsm_info);
    if(NULL == audio_dclient)
    {
        printk("audio_dclient register failed!\n");
    }

    return 0;
}
예제 #8
0
static void __init dsm_register_public_client(void)
{
	int index;
	struct dsm_client *client = NULL;

	for(index = 0; index < ARRAY_SIZE(dsm_pub_clients); index++){
		client = dsm_register_client(&dsm_pub_clients[index]);
		if(client)
			DSM_LOG_DEBUG("register %d public client - %s success\n", index,
				dsm_pub_clients[index].name);
		else
			DSM_LOG_ERR("register %d public client - %s failed\n", index,
				dsm_pub_clients[index].name);
	}
}
static int __init bluetooth_dsm_init(void)
{
    int retval = -EIO;
    
    if(!bt_dclient){
       bt_dclient = dsm_register_client (&dsm_bt);
    }

    retval = misc_register(&bluetooth_miscdev);
    if (retval) {
        pr_err("%s: misc_register err %d\n",
            __func__, retval);
        return retval;
    }
    
    return 0;
}
예제 #10
0
/*****************************************************************************
 函 数 名  : pastar_adp_init
 功能描述  : pastar 适配层初始化
 输入参数  : 无
 输出参数  : 无
 返 回 值  : 0 - 成功; else - 失败
*****************************************************************************/
s32 pastar_adp_init(void)
{    
    s32 ret = ERROR;

    pastar_print_info("Execuing ...");
    
    /* icc register */
    ret = bsp_icc_event_register(PASTAR_ICC_CHN_ID, pastar_notify_exception, NULL, NULL, NULL);
	if(ret != OK)
	{
        pastar_print_error("icc register failed, ret = %d\n", ret);
        return ret;
	}

    /* dclient register */
    if(!pastar_dclient) 
    {
		pastar_dclient = dsm_register_client(&dsm_pastar);
        if(!pastar_dclient)
    	{
            pastar_print_error("dsm_register_client failed\n");
            return ERROR;
    	}
	}

    /* create work queue */
    pastar_dsm_wq = create_singlethread_workqueue("pastar_dsm_wq");
	if (IS_ERR(pastar_dsm_wq))
    {
        pastar_print_error("create workqueue failed\n");
        return ERROR;
	}

	INIT_WORK(&pastar_dsm_work, pastar_dsm_work_func);

    pastar_print_always("PAStar init OK\n");

    /* success */
    return OK;
}
static int hisi_pmic_mntn_probe(struct platform_device *pdev)
{
    struct device *dev = &pdev->dev;
    struct device_node *np = dev->of_node;
    PMIC_MNTN_DESC *pmic_mntn = NULL;
    int ret = 0;

    pmic_mntn = (PMIC_MNTN_DESC *)devm_kzalloc(dev, sizeof(*pmic_mntn), GFP_KERNEL);
    if (NULL == pmic_mntn) {
        dev_err(dev, "[%s]devm_kzalloc pmic_mntn err\n", __func__);
        return -ENOMEM;
    }

    g_pmic_mntn = pmic_mntn;
    pmic_mntn->health = PMIC_HEALTH_STATUS_NORMAL;

    pmic_mntn->init_log_show = (char *)devm_kzalloc(dev, PMIC_PRINT_BUF_SIZE, GFP_KERNEL);
    if (NULL == pmic_mntn->init_log_show) {
        dev_err(dev, "[%s]devm_kzalloc init_log_show err\n", __func__);
        return -ENOMEM;
    }

    pmic_mntn->irq_log_show = (char *)devm_kzalloc(dev, PMIC_PRINT_BUF_SIZE, GFP_KERNEL);
    if (NULL == pmic_mntn->irq_log_show) {
        dev_err(dev, "[%s]devm_kzalloc irq_log_show err\n", __func__);
        return -ENOMEM;
    }

    ret = of_property_read_u32(np, "hisilicon,data-width", &pmic_mntn->data_width);
    if (ret) {
        dev_err(dev, "[%s]get pmic data-width failed.\n", __func__);
        return -ENODEV;
    }

    ret = hisi_ocp_mold_switch_initial(pdev, pmic_mntn);
    if (ret) {
        dev_err(dev, "[%s]hisi_ocp_mold_switch_initial error.\n", __func__);
        return ret;
    }

    ret = hisi_pmu_key_register_record_initial(pdev, pmic_mntn);
    if (ret) {
        dev_err(dev, "[%s]hisi_pmu_key_register_record_initial error.\n", __func__);
        return ret;
    }

    ret = hisi_pmic_otmp_mntn_initial(pdev, pmic_mntn);
    if (ret) {
        dev_err(dev, "[%s]hisi_pmic_otmp_mntn_initial error.\n", __func__);
        return ret;
    }

    ret = hisi_pmic_smpl_mntn_initial(pdev, pmic_mntn);
    if (ret) {
        dev_err(dev, "[%s]hisi_pmic_smpl_mntn_initial error.\n", __func__);
        return ret;
    }

    /*just read dtsi vsys_pwroff_abs_pd  property */
    ret = hisi_pmic_vsys_pwroff_abs_pd_mntn_initial(pdev, pmic_mntn);
    if (ret ) {
        dev_err(dev, "[%s]hisi_pmic_vsys_pwroff_abs_pd_mntn_initial error.\n", __func__);
        return ret;
    }

    ret = hisi_pmic_ocp_mntn_initial(pdev, pmic_mntn);
    if (ret) {
        dev_err(dev, "[%s]hisi_pmic_ocp_mntn_initial error.\n", __func__);
        return ret;
    }

    ret = hisi_pmic_record_mntn_initial(pdev, pmic_mntn);
    if (ret) {
        dev_err(dev, "[%s]hisi_pmic_record_mntn_initial error.\n", __func__);
        return ret;
    }

    if (get_uv_mntn_status()) {
        ret = hisi_pmic_uv_mntn_initial(pdev, pmic_mntn);
        if (ret) {
            dev_err(dev, "[%s]hisi_pmic_uv_mntn_initial error.\n", __func__);
            return ret;
        }
    }

#if defined (CONFIG_HUAWEI_DSM)
    if (!pmic_dsm_dclient) {
        pmic_dsm_dclient = dsm_register_client(&pmic_dsm_dev);
		if (NULL == pmic_dsm_dclient) {
			dev_err(dev, "[%s]dsm_register_client register fail.\n", __func__);
		}
    }
#endif

    hisi_pmic_record_events(pmic_mntn);

    ret = hisi_pmic_register_special_ocp();
    if (ret) {
        dev_err(dev, "[%s]hisi_pmic_register_special_ocp error.\n", __func__);
        return ret;
    }

    return 0;
}
static int hi6402_mbhc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct hi6402_mbhc_platform_data *pdata = NULL;
	const struct of_device_id *match = NULL;
	int ret = 0;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (NULL == pdata) {
		dev_err(dev, "cannot allocate hisi 6421 spk platform data\n");
		return -ENOMEM;
	}

	match = of_match_device(hi6402_mbhc_of_match, dev);
	if (!match) {
		pr_err("get device info err\n");
		return -ENOENT;
	} else {
		struct device_node *node = dev->of_node;
		int temp;

		/* get board defination */
		if (!of_property_read_u32(node, "hisilicon,hi6402_hs_det_inv", &temp))
			pdata->hs_det_inv = temp;
		else
			pdata->hs_det_inv = 0;

		if (!of_property_read_u32(node, "hisilicon,hs_3_pole_min_voltage", &temp))
			pdata->hs_3_pole_min_voltage = temp;
		else
			pdata->hs_3_pole_min_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,hs_3_pole_max_voltage", &temp))
			pdata->hs_3_pole_max_voltage = temp;
		else
			pdata->hs_3_pole_max_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,hs_4_pole_min_voltage", &temp))
			pdata->hs_4_pole_min_voltage = temp;
		else
			pdata->hs_4_pole_min_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,hs_4_pole_max_voltage", &temp))
			pdata->hs_4_pole_max_voltage = temp;
		else
			pdata->hs_4_pole_max_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,btn_play_min_voltage", &temp))
			pdata->btn_play_min_voltage = temp;
		else
			pdata->btn_play_min_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,btn_play_max_voltage", &temp))
			pdata->btn_play_max_voltage = temp;
		else
			pdata->btn_play_max_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,btn_volume_up_min_voltage", &temp))
			pdata->btn_volume_up_min_voltage = temp;
		else
			pdata->btn_volume_up_min_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,btn_volume_up_max_voltage", &temp))
			pdata->btn_volume_up_max_voltage = temp;
		else
			pdata->btn_volume_up_max_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,btn_volume_down_min_voltage", &temp))
			pdata->btn_volume_down_min_voltage = temp;
		else
			pdata->btn_volume_down_min_voltage = 0;

		if (!of_property_read_u32(node, "hisilicon,btn_volume_down_max_voltage", &temp))
			pdata->btn_volume_down_max_voltage = temp;
		else
			pdata->btn_volume_down_max_voltage = 0;
	}

	pdata->p_irq = dev_get_drvdata(pdev->dev.parent);
	if (!pdata->p_irq) {
		dev_err(dev, "get parend device error\n");
		return -ENOENT;
	}

#ifdef CONFIG_SWITCH
	pdata->sdev.name = "h2w";
	ret = switch_dev_register(&pdata->sdev);
	if (ret) {
		pr_err("%s : error registering switch device %d\n", __FUNCTION__, ret);
		return ret;
	}
#endif

	/* get irqs */
	pdata->irq[HI6402_IRQ_PLL_UNLOCK] = platform_get_irq_byname(pdev, "pll_unlock");
	if (0 > pdata->irq[HI6402_IRQ_PLL_UNLOCK]) {
		pr_err("get pll unlock error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_SOUND_TRIGER] = platform_get_irq_byname(pdev, "sound_triger");
	if (0 > pdata->irq[HI6402_IRQ_SOUND_TRIGER]) {
		pr_err("get sound triger error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_PLUGOUT] = platform_get_irq_byname(pdev, "plugout");
	if (0 > pdata->irq[HI6402_IRQ_PLUGOUT]) {
		pr_err("get plug out irq num error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_PLUGIN] = platform_get_irq_byname(pdev, "plugin");
	if (0 > pdata->irq[HI6402_IRQ_PLUGIN]) {
		pr_err("get plug in irq num error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_BTNDOWN_ECO] = platform_get_irq_byname(pdev, "btndown_eco");
	if (0 > pdata->irq[HI6402_IRQ_BTNDOWN_ECO]) {
		pr_err("get btn down eco irq num error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_BTNUP_ECO] = platform_get_irq_byname(pdev, "btnup_eco");
	if (0 > pdata->irq[HI6402_IRQ_BTNUP_ECO]) {
		pr_err("get btn up eco irq num error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_BTNDOWN_COMP1] = platform_get_irq_byname(pdev, "btndown");
	if (0 > pdata->irq[HI6402_IRQ_BTNDOWN_COMP1]) {
		pr_err("get btn down irq num error");
		return -ENOENT;
	}

	pdata->irq[HI6402_IRQ_BTNUP_COMP1] = platform_get_irq_byname(pdev, "btnup");
	if (0 > pdata->irq[HI6402_IRQ_BTNUP_COMP1]) {
		pr_err("get btn up irq num error");
		return -ENOENT;
	}

	wake_lock_init(&pdata->wake_lock, WAKE_LOCK_SUSPEND, "hisi-6402-mbhc");
	wake_lock_init(&pdata->soundtrigger_wake_lock, WAKE_LOCK_SUSPEND, "hisi-6402-soundtrigger");
	mutex_init(&pdata->plug_mutex);
	mutex_init(&pdata->status_mutex);
	mutex_init(&pdata->saradc_mutex);

	/* irq request : pll unlock */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_PLL_UNLOCK], NULL,
					hi6402_pll_unlock_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"pll_unlock", pdata);
	if (0 > ret) {
		pr_err("request irq for pll unlock err\n");
		goto pll_unlock_err;
	}
	mutex_lock(&pdata->p_irq->irq_lock);
	hi6402_reg_set_bit(pdata->p_irq, HI6402_MASK_IRQ_REG_2, HI6402_MASK_PLL_UNLOCK_BIT);
	pdata->p_irq->mask2 |= 0x10;
	mutex_unlock(&pdata->p_irq->irq_lock);

	/* irq request : sound triger */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_SOUND_TRIGER], NULL,
					hi6402_sound_triger_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"sound_triger", pdata);
	if (0 > ret) {
		pr_err("request irq for sound triger err\n");
		goto sound_triger_err;
	}

	/* irq request : plugout */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_PLUGOUT], NULL,
					hi6402_plugout_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"plugout", pdata);
	if (0 > ret) {
		pr_err("request irq for plugout err\n");
		goto plugout_err;
	}

	/* irq request : plugin */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_PLUGIN], NULL,
					hi6402_plugin_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"plugin", pdata);
	if (0 > ret) {
		pr_err("request irq for plugin err\n");
		goto plugin_err;
	}

	/* irq request : button up(eco mode) */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_BTNUP_ECO], NULL,
					hi6402_btnup_eco_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"btnup_eco", pdata);
	if (0 > ret) {
		pr_err("request irq for btnup eco err\n");
		goto btnup_eco_err;
	}

	/* irq request : button down(eco mode) */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_BTNDOWN_ECO], NULL,
					hi6402_btndown_eco_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"btndown_eco", pdata);
	if (0 > ret) {
		pr_err("request irq for btndown eco err\n");
		goto btndown_eco_err;
	}

	/* irq request : button down */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], NULL,
					hi6402_btndown_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"btndown_comp1", pdata);
	if (0 > ret) {
		pr_err("request irq for btndown comp1 err\n");
		goto btndown_comp1_err;
	}

	/* irq request : button up */
	ret = devm_request_threaded_irq(dev, pdata->irq[HI6402_IRQ_BTNUP_COMP1], NULL,
					hi6402_btnup_handler,
					IRQF_NO_SUSPEND | IRQF_ONESHOT,
					"btnup_comp1", pdata);
	if (0 > ret) {
		pr_err("request irq for btnup comp1 err\n");
		goto btnup_comp1_err;
	}

	hi6402_irq_mask_btn_irqs(pdata->p_irq);
	hi6402_irq_clr_btn_irqs(pdata->p_irq);
	
	/* enable hsdet */
	hi6402_irq_write(pdata->p_irq, HI6402_REG_HSDET_CTRL, 0x19);
	hi6402_irq_write(pdata->p_irq, HI6402_MBHC_VREF_REG, 0x8E);

	//register anc hs first
	anc_hs_dev_register(&anc_dev, pdata);

	//register soundtrigger input device.
	ret = soundtrigger_input_init(dev);
	if(ret)
		pr_err("input registor failed: %d\n", ret);

#if 0
	/* check jack at first time */
	if (check_headset_pluged_in(pdata))
		hi6402_plug_in_detect(pdata);
#endif

	pdata->miscdev.minor = MISC_DYNAMIC_MINOR;
	pdata->miscdev.name = "hi6402_mbhc";

	ret = misc_register(&pdata->miscdev);
	if (ret) {
		loge("%s : hisi 6421 spk_device register failed", __FUNCTION__);
		goto btnup_comp1_err;
	}

	if (!dsm_audio_client) {
		dsm_audio_client = dsm_register_client(&dsm_audio);
	}

	pr_info("%s : hi6402 mbhc probe ok \n", __FUNCTION__);

	return ret;

btnup_comp1_err:
	free_irq(pdata->irq[HI6402_IRQ_BTNDOWN_COMP1], pdata);
btndown_comp1_err:
	free_irq(pdata->irq[HI6402_IRQ_BTNDOWN_ECO], pdata);
btndown_eco_err:
	free_irq(pdata->irq[HI6402_IRQ_BTNUP_ECO], pdata);
btnup_eco_err:
	free_irq(pdata->irq[HI6402_IRQ_PLUGIN], pdata);
plugin_err:
	free_irq(pdata->irq[HI6402_IRQ_PLUGOUT], pdata);
plugout_err:
	free_irq(pdata->irq[HI6402_IRQ_SOUND_TRIGER], pdata);
sound_triger_err:
	free_irq(pdata->irq[HI6402_IRQ_PLL_UNLOCK], pdata);
pll_unlock_err:
	wake_lock_destroy(&pdata->soundtrigger_wake_lock);
	wake_lock_destroy(&pdata->wake_lock);
	mutex_destroy(&pdata->plug_mutex);
	mutex_destroy(&pdata->status_mutex);

	return ret;
}
static int hisi_battery_data_probe(struct platform_device *pdev)
{
    int retval;
    unsigned int i;
    struct device_node* np;
    struct device_node* bat_node;
    //get device node for battery module

    bat_param_status = 0;
    np = pdev->dev.of_node;
    if(NULL == np)
    {
        hwlog_err("get device node failed\n");
        goto fatal_err;
    }

    //get numeber of types
    for (i = 0; ; ++i)
    {
        if (!of_parse_phandle(np, "batt_name", i))
        {
            break;
        }
    }
    if (0 == i)
    {
        hwlog_err("hisi_bat_data_size is zero\n");
        goto fatal_err;
    }
    hisi_bat_data_size = i;
    hwlog_info("hisi_bat_data_size = %u\n", hisi_bat_data_size);

    //alloc memory to store pointers(point to battery data)
    p_data = (struct hisi_hi6421v300_coul_battery_data**)kzalloc(hisi_bat_data_size * sizeof(struct hisi_hi6421v300_coul_battery_data*), GFP_KERNEL);
    if (!p_data)
    {
        hwlog_err("alloc memory for p_data failed\n");
        goto fatal_err;
    }

    for(i = 0; i < hisi_bat_data_size; ++i)
    {
        retval = get_mem(&(p_data[i]));
        if (retval)
        {
            hwlog_err("get_mem[%d] failed\n", i);
            goto fatal_err;
        }
        bat_node = of_parse_phandle(np, "batt_name", i);
        if (NULL == bat_node)
        {
            hwlog_err("get bat_node failed\n");
            goto fatal_err;
        }
        retval = get_dat(bat_node, p_data[i]);
        if (retval)
        {
            hwlog_err("get_dat[%d] failed\n", i);
            goto fatal_err;
        }
    }
    platform_set_drvdata(pdev, p_data);
    bat_param_status = 1;

    if (!battery_detect_dclient) {
        battery_detect_dclient = dsm_register_client(&dsm_battery_detect);
    }
    hwlog_info("probe ok\n");
    return 0;
fatal_err:
    if (NULL != p_data)
    {
         for(i = 0; i < hisi_bat_data_size; ++i)
        {
            free_mem(&(p_data[i]));
        }
        kfree(p_data);
    }
    p_data = NULL;
    BUG();
    return -EINVAL;
}
static int hisi_gpio_key_probe(struct platform_device* pdev)
{
	struct hisi_gpio_key *gpio_key = NULL;
	struct input_dev *input_dev = NULL;
	enum of_gpio_flags flags;
	int err =0;

	if (NULL == pdev) {
		printk(KERN_ERR "[gpiokey]parameter error!\n");
		return -EINVAL;
	}

	dev_info(&pdev->dev, "hisi gpio key driver probes start!\n");
#ifdef CONFIG_OF
	if (!of_match_node(hs_gpio_key_match, pdev->dev.of_node)) {
		dev_err(&pdev->dev, "dev node is not match. exiting.\n");
		return -ENODEV;
	}
#endif

	gpio_key = devm_kzalloc(&pdev->dev, sizeof(struct hisi_gpio_key), GFP_KERNEL);
	if (!gpio_key) {
		dev_err(&pdev->dev, "Failed to allocate struct hisi_gpio_key!\n");
		return -ENOMEM;
	}

	input_dev = input_allocate_device();
	if (!input_dev) {
		dev_err(&pdev->dev, "Failed to allocate struct input_dev!\n");
		return -ENOMEM;
	}

	input_dev->name = pdev->name;
	input_dev->id.bustype = BUS_HOST;
	input_dev->dev.parent = &pdev->dev;
	input_set_drvdata(input_dev, gpio_key);
	set_bit(EV_KEY, input_dev->evbit);
	set_bit(EV_SYN, input_dev->evbit);
	set_bit(KEY_VOLUMEUP, input_dev->keybit);
	set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	set_bit(KEY_BACK, input_dev->keybit);
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	set_bit(KEY_F24, input_dev->keybit);
#endif
	input_dev->open = hisi_gpio_key_open;
	input_dev->close = hisi_gpio_key_close;

	gpio_key->input_dev = input_dev;

	/*initial work before we use it.*/
	INIT_DELAYED_WORK(&(gpio_key->gpio_keyup_work), hisi_gpio_keyup_work);
	INIT_DELAYED_WORK(&(gpio_key->gpio_keydown_work), hisi_gpio_keydown_work);
	wake_lock_init(&volume_down_key_lock, WAKE_LOCK_SUSPEND, "key_down_wake_lock");
	wake_lock_init(&volume_up_key_lock, WAKE_LOCK_SUSPEND, "key_up_wake_lock");
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	INIT_DELAYED_WORK(&(gpio_key->gpio_keyback_work), hisi_gpio_keyback_work);
	wake_lock_init(&back_key_lock, WAKE_LOCK_SUSPEND, "key_back_wake_lock");
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	INIT_DELAYED_WORK(&(gpio_key->gpio_keysmart_work), hisi_gpio_keysmart_work);
	wake_lock_init(&smart_key_lock, WAKE_LOCK_SUSPEND, "key_smart_wake_lock");
#endif

	gpio_key->gpio_up = of_get_key_gpio(pdev->dev.of_node, "gpio-keyup,gpio-irq", 0, 0, &flags);
	if (!gpio_is_valid(gpio_key->gpio_up)) {
		printk(KERN_INFO "%s: gpio of volume up is not valid, check DTS\n", __FUNCTION__);
	}

	gpio_key->gpio_down = of_get_key_gpio(pdev->dev.of_node, "gpio-keydown,gpio-irq", 0, 0, &flags);
	if (!gpio_is_valid(gpio_key->gpio_down)) {
		printk(KERN_INFO "%s: gpio of volume down is not valid, check DTS\n", __FUNCTION__);
	}

#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	gpio_key->gpio_back = of_get_key_gpio(pdev->dev.of_node, "gpio-keyback,gpio-irq", 0, 0, &flags);
	if (!gpio_is_valid(gpio_key->gpio_back)) {
		printk(KERN_INFO "%s: gpio of back key is not valid, check DTS\n", __FUNCTION__);
	}
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	gpio_key->gpio_smart = of_get_key_gpio(pdev->dev.of_node, "gpio-keysmart,gpio-irq", 0, 0, &flags);
	if (!gpio_is_valid(gpio_key->gpio_smart)) {
		printk(KERN_INFO "%s: gpio of smart key is not valid, check DTS\n", __FUNCTION__);
	}
#endif

	vol_up_gpio = gpio_key->gpio_up;
	vol_up_active_low = GPIO_KEY_PRESS;
	vol_down_gpio = gpio_key->gpio_down;
	vol_down_active_low = GPIO_KEY_PRESS;

	if (gpio_is_valid(gpio_key->gpio_up)) {
		err = gpio_request((unsigned int)gpio_key->gpio_up, "gpio_up");
		if (err < 0) {
			dev_err(&pdev->dev, "Fail request gpio:%d\n", gpio_key->gpio_up);
			goto err_get_gpio;
		}

		gpio_direction_input((unsigned int)gpio_key->gpio_up);

		gpio_key->volume_up_irq = gpio_to_irq((unsigned int)gpio_key->gpio_up);
		if (gpio_key->volume_up_irq < 0) {
			dev_err(&pdev->dev, "Failed to get gpio key press irq!\n");
			err = gpio_key->volume_up_irq;
			goto err_gpio_to_irq;
		}
	}
	if (gpio_is_valid(gpio_key->gpio_down)) {
		err = gpio_request((unsigned int)gpio_key->gpio_down, "gpio_down");
		if (err) {
			dev_err(&pdev->dev, "Fail request gpio:%d\n", gpio_key->gpio_down);
			goto err_gpio_down_req;
		}

		gpio_direction_input((unsigned int)gpio_key->gpio_down);

		gpio_key->volume_down_irq = gpio_to_irq((unsigned int)gpio_key->gpio_down);
		if (gpio_key->volume_down_irq < 0) {
			dev_err(&pdev->dev, "Failed to get gpio key release irq!\n");
			err = gpio_key->volume_down_irq;
			goto err_gpio_to_irq;
		}
	}
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	if (gpio_is_valid(gpio_key->gpio_back)) {
		err = gpio_request((unsigned int)gpio_key->gpio_back, "gpio_back");
		if (err) {
			dev_err(&pdev->dev, "Fail request gpio:%d\n", gpio_key->gpio_back);
			goto err_gpio_back_req;
		}

		gpio_direction_input((unsigned int)gpio_key->gpio_back);

		gpio_key->key_back_irq = gpio_to_irq((unsigned int)gpio_key->gpio_back);
		if (gpio_key->key_back_irq < 0) {
			dev_err(&pdev->dev, "Failed to get gpio key release irq!\n");
			err = gpio_key->key_back_irq;
			goto err_gpio_to_irq;
		}
	}
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	if (gpio_is_valid(gpio_key->gpio_smart)) {
		err = gpio_request((unsigned int)gpio_key->gpio_smart, "gpio_smart");
		if (err) {
			dev_err(&pdev->dev, "Fail request gpio:%d\n", gpio_key->gpio_smart);
			goto err_gpio_smart_req;
		}

		gpio_direction_input((unsigned int)gpio_key->gpio_smart);

		gpio_key->key_smart_irq = gpio_to_irq((unsigned int)gpio_key->gpio_smart);
		if (gpio_key->key_smart_irq < 0) {
			dev_err(&pdev->dev, "Failed to get gpio key release irq!\n");
			err = gpio_key->key_smart_irq;
			goto err_gpio_to_irq;
		}
	}
#endif

	gpio_key->pctrl = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(gpio_key->pctrl)) {
		dev_err(&pdev->dev, "failed to devm pinctrl get\n");
		err = -EINVAL;
		goto err_pinctrl;
	}
	gpio_key->pins_default = pinctrl_lookup_state(gpio_key->pctrl, PINCTRL_STATE_DEFAULT);
	if (IS_ERR(gpio_key->pins_default)) {
		dev_err(&pdev->dev, "failed to pinctrl lookup state default\n");
		err = -EINVAL;
		goto err_pinctrl_put;
	}
	gpio_key->pins_idle = pinctrl_lookup_state(gpio_key->pctrl, PINCTRL_STATE_IDLE);
	if (IS_ERR(gpio_key->pins_idle)) {
		dev_err(&pdev->dev, "failed to pinctrl lookup state idle\n");
		err = -EINVAL;
		goto err_pinctrl_put;
	}
	err = pinctrl_select_state(gpio_key->pctrl, gpio_key->pins_default);
	if (err < 0) {
		dev_err(&pdev->dev, "set iomux normal error, %d\n", err);
		goto err_pinctrl_put;
	}

#if defined (CONFIG_HUAWEI_DSM)
	/* initialize the statistic variable */
	volume_up_press_count = 0;
	volume_down_press_count = 0;
	volume_up_last_press_time = 0;
	volume_down_last_press_time = 0;
#endif

	setup_timer(&(gpio_key->key_up_timer), gpio_keyup_timer, (unsigned long )gpio_key);
	setup_timer(&(gpio_key->key_down_timer), gpio_keydown_timer, (unsigned long )gpio_key);
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	setup_timer(&(gpio_key->key_back_timer), gpio_keyback_timer, (unsigned long )gpio_key);
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	setup_timer(&(gpio_key->key_smart_timer), gpio_keysmart_timer, (unsigned long )gpio_key);
#endif

#if defined (CONFIG_HUAWEI_DSM)
	setup_timer(&dsm_gpio_key_timer, dsm_gpio_key_timer_func, (unsigned long)gpio_key);
#endif
	/*
	 * support failing irq that means volume-up-key is pressed,
	 * and rising irq which means volume-up-key is released.
	 */
	 if (gpio_is_valid(gpio_key->gpio_up)) {
		err = request_irq(gpio_key->volume_up_irq, hisi_gpio_key_irq_handler, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, pdev->name, gpio_key);
		if (err) {
			dev_err(&pdev->dev, "Failed to request press interupt handler!\n");
			goto err_up_irq_req;
		}
	 }

	/*
	 * support failing irq that means volume-down-key is pressed,
	 * and rising irq which means volume-down-key is released.
	 */
	 if (gpio_is_valid(gpio_key->gpio_down)) {
		err = request_irq(gpio_key->volume_down_irq, hisi_gpio_key_irq_handler, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, pdev->name, gpio_key);
		if (err) {
			dev_err(&pdev->dev, "Failed to request release interupt handler!\n");
			goto err_down_irq_req;
		}
	 }

#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	if (gpio_is_valid(gpio_key->gpio_back)) {
		err = request_irq(gpio_key->key_back_irq, hisi_gpio_key_irq_handler, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, pdev->name, gpio_key);
		if (err) {
			dev_err(&pdev->dev, "Failed to request release interupt handler!\n");
			goto err_back_irq_req;
		}
	}
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	if (gpio_is_valid(gpio_key->gpio_smart)) {
		err = request_irq(gpio_key->key_smart_irq, hisi_gpio_key_irq_handler, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, pdev->name, gpio_key);
		if (err) {
			dev_err(&pdev->dev, "Failed to request release interupt handler!\n");
			goto err_smart_irq_req;
		}
	}
#endif

	err = input_register_device(gpio_key->input_dev);
	if (err) {
		dev_err(&pdev->dev, "Failed to register input device!\n");
		goto err_register_dev;
	}

	device_init_wakeup(&pdev->dev, TRUE);
	platform_set_drvdata(pdev, gpio_key);

#if defined (CONFIG_HUAWEI_DSM)
	if (!key_dclient) {
		key_dclient = dsm_register_client(&dsm_key);
	}

	mod_timer(&dsm_gpio_key_timer, jiffies + STATISTIC_INTERVAL * HZ);
#endif

	dev_info(&pdev->dev, "hisi gpio key driver probes successfully!\n");
	return 0;

err_register_dev:
#ifdef  CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	free_irq(gpio_key->key_back_irq, gpio_key);
err_back_irq_req:
#endif
#ifdef  CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	free_irq(gpio_key->key_smart_irq, gpio_key);
err_smart_irq_req:
#endif
	free_irq(gpio_key->volume_down_irq, gpio_key);
err_down_irq_req:
	free_irq(gpio_key->volume_up_irq, gpio_key);
err_up_irq_req:
err_pinctrl_put:
	devm_pinctrl_put(gpio_key->pctrl);
err_pinctrl:
err_gpio_to_irq:
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	gpio_free((unsigned int)gpio_key->gpio_back);
err_gpio_back_req:
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	gpio_free((unsigned int)gpio_key->gpio_smart);
err_gpio_smart_req:
#endif
	gpio_free((unsigned int)gpio_key->gpio_down);
err_gpio_down_req:
	gpio_free((unsigned int)gpio_key->gpio_up);
err_get_gpio:
	input_free_device(input_dev);
	wake_lock_destroy(&volume_down_key_lock);
	wake_lock_destroy(&volume_up_key_lock);
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_HI6XXX
	wake_lock_destroy(&back_key_lock);
#endif
#ifdef CONFIG_HISI_GPIO_KEY_SUPPORT_SMART_KEY
	wake_lock_destroy(&smart_key_lock);
#endif
	pr_info(KERN_ERR "[gpiokey]K3v3 gpio key probe failed! ret = %d.\n", err);
	return err;
}
void hw_register_wifi_dsm_client(void) {
    if(NULL == wifi_dsm_client) {
        wifi_dsm_client = dsm_register_client(&dsm_wifi);
    }
}
static int ivp_smmu_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct ivp_smmu_dev *smmu_dev  = NULL;
    struct iommu_domain_data *domain_info = NULL;
	struct resource *res = NULL; 
	unsigned int *ver = NULL;
    int ret = 0;
	    
	pr_info("%s: smmu driver start\n",__func__);
	
	smmu_dev = devm_kzalloc(&pdev->dev, sizeof(*smmu_dev), GFP_KERNEL);
	if (!smmu_dev){
		pr_err("%s: devm_kzalloc is failed\n", __func__);
        return -ENOMEM;
	}
	smmu_dev->dev = &pdev->dev;
    smmu_dev->state = SMMU_STATE_DISABLE;

	/* get smmu version */
	ver = (unsigned int *)of_get_property(np, "hisi,smmu-version", NULL);
	if (ver) {
		smmu_dev->version = be32_to_cpu(*ver); 
		pr_info("%s: smmu version is %u\n", __func__, be32_to_cpu(*ver));
	}

	/* get IOMEM resource */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		pr_err("%s:platform_get_resource err\n", __func__);
		return -ENOENT;
	}
	smmu_dev->reg_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(smmu_dev->reg_base)) {
        pr_err("%s: remap resource err\n", __func__);
		return PTR_ERR(smmu_dev->reg_base);
    }
	smmu_dev->reg_size = resource_size(res);

	/* get IRQ resource */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res){
		pr_err("%s: get IRQ IS failed\n", __func__);
		return -ENOENT;
	}
	smmu_dev->irq = (unsigned int)res->start;
	smmu_dev->isr = ivp_smmu_isr;

	/**
	 * get domain and physical pgd base address
	 */
	smmu_dev->domain = iommu_domain_alloc(pdev->dev.bus);
	if (!smmu_dev->domain) {
		pr_err("%s: get domain failed\n", __func__);
		return -ENODEV;
	} else {
		ret = iommu_attach_device(smmu_dev->domain, &pdev->dev);
        if (ret) {
            iommu_domain_free(smmu_dev->domain);
    		pr_err("%s: iommu attach failed ret[0x%x]\n", __func__, ret);
    		return -ENODEV;
        }
        
		domain_info = (struct iommu_domain_data *)smmu_dev->domain->priv;
        smmu_dev->pgd_base = (unsigned long)domain_info->phy_pgd_base;
	}

	/**
	 * for the ivp subsys, only support:
	 * Context Bank:0; Virtual Machine ID:0; CB attribute:S1_TRANS_S2_BYPASS
	 */
	smmu_dev->cbidx = SMMU_CB_IDX_IVP;
	smmu_dev->vmid  = SMMU_CB_VMID_IVP;
	smmu_dev->cbar  = SMMU_CBAR_TYPE_S1_TRANS_S2_BYPASS;

    spin_lock_init(&smmu_dev->spinlock);
    g_smmu_dev = smmu_dev;

	pr_info("%s: smmu driver probes finish\n", __func__);

    if(client_ivp == NULL)
    {
        client_ivp = dsm_register_client(&dev_ivp);
    }

	return 0;
}
static int hisi_powerkey_probe(struct platform_device *pdev)
{
    struct hisi_powerkey_info *info = NULL;
    struct device *dev = &pdev->dev;
    int ret = 0;

    if(NULL == pdev) {
        dev_err(dev, "[Pwrkey]parameter error!\n");
        ret = -EINVAL;
        return ret;
    }

#ifdef CONFIG_FB_HI6220_CLCD
	init_timer(&lcd_pwr_status.lcd_dsm_t);
	lcd_pwr_status.panel_power_on = true;
#endif
    info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
    if (!info)
        return -ENOMEM;

	info->idev = input_allocate_device();
	if (!info->idev) {
		dev_err(&pdev->dev, "Failed to allocate input device\n");
		ret = -ENOENT;
		return ret;
	}

	info->idev->name = "hisi_on";
	info->idev->phys = "hisi_on/input0";
	info->idev->dev.parent = &pdev->dev;
	info->idev->evbit[0] = BIT_MASK(EV_KEY);
	__set_bit(KEY_POWER, info->idev->keybit);

	wake_lock_init(&info->pwr_wake_lock, WAKE_LOCK_SUSPEND, "android-pwr");


#if defined (CONFIG_HUAWEI_DSM)
	/* initialize the statistic variable */
	powerkey_press_count = 0;
	powerkey_last_press_time = 0;
	setup_timer(&dsm_powerkey_timer, powerkey_timer_func, (unsigned long)info);
#endif

	info->irq[0] = platform_get_irq_byname(pdev, "down");
	if (info->irq[0] < 0) {
		dev_err(dev, "failed to get down irq id\n");
		ret = -ENOENT;
		goto unregister_err;
	}

	ret = devm_request_irq(dev, info->irq[0], hisi_powerkey_handler,
			       IRQF_NO_SUSPEND, "down", info);
	if (ret < 0) {
		dev_err(dev, "failed to request down irq\n");
		ret = -ENOENT;
		goto unregister_err;
	}

	info->irq[1] = platform_get_irq_byname(pdev, "up");
	if (info->irq[1] < 0) {
		dev_err(dev, "failed to get up irq id\n");
		ret = -ENOENT;
		goto unregister_err;
	}

	ret = devm_request_irq(dev, info->irq[1], hisi_powerkey_handler,
			       IRQF_NO_SUSPEND, "up", info);
	if (ret < 0) {
		dev_err(dev, "failed to request up irq\n");
		ret = -ENOENT;
		goto unregister_err;
	}

	info->irq[2] = platform_get_irq_byname(pdev, "hold 1s");
	if (info->irq[2] < 0) {
		dev_err(dev, "failed to get hold 1s irq id\n");
		ret = -ENOENT;
		goto unregister_err;
	}

	ret = devm_request_irq(dev, info->irq[2], hisi_powerkey_handler,
			       IRQF_DISABLED, "hold 1s", info);
	if (ret < 0) {
		dev_err(dev, "failed to request hold 1s irq\n");
		ret = -ENOENT;
		goto unregister_err;
	}

	info->irq[3] = platform_get_irq_byname(pdev, "hold 8s");
	if (info->irq[3] >= 0) {
		ret = devm_request_irq(dev, info->irq[3], hisi_powerkey_handler,
				       IRQF_DISABLED, "hold 8s", info);
		if (ret < 0) {
			dev_err(dev, "failed to request hold 8s irq\n");
			ret = -ENOENT;
			goto unregister_err;
		}
	}

	info->irq[4] = platform_get_irq_byname(pdev, "hold 10s");
	if (info->irq[4] >= 0) {
		ret = devm_request_irq(dev, info->irq[4], hisi_powerkey_handler,
				       IRQF_DISABLED, "hold 10s", info);
		if (ret < 0) {
			dev_err(dev, "failed to request hold 10s irq\n");
			ret = -ENOENT;
			goto unregister_err;
		}
	}

	ret = input_register_device(info->idev);
	if (ret) {
		dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
		ret = -ENOENT;
		goto input_err;
	}

	platform_set_drvdata(pdev, info);

#if defined (CONFIG_HUAWEI_DSM)
	if (!power_key_dclient) {
		power_key_dclient = dsm_register_client(&dsm_power_key);
	}
	mod_timer(&dsm_powerkey_timer, jiffies + STATISTIC_INTERVAL * HZ);
#endif

	return ret;

input_err:
unregister_err:
	wake_lock_destroy(&info->pwr_wake_lock);
	input_free_device(info->idev);

	return ret;
}
예제 #18
0
static int bq_bci_battery_probe(struct platform_device *pdev)
{
    struct bq_bci_device_info *di;
    struct battery_charge_param_s param;
    int low_bat_flag = 0;
    int ret = 0;
    unsigned int i = 0;

    di = kzalloc(sizeof(*di), GFP_KERNEL);
    if (!di)
        return -ENOMEM;
    g_bq_bci_dev = di;

    ret = hisi_battery_charge_param(&param);
    if(!ret){
        param.max_voltagemV = 4200;
    }

    di->bat_max_volt = param.max_voltagemV;
    di->monitoring_interval = NORMAL_SAMPLE_INTERVAL;
    di->dev = &pdev->dev;
    di->bat.name = "Battery";
    di->bat.supplied_to = bq_bci_supplied_to;
    di->bat.num_supplicants = ARRAY_SIZE(bq_bci_supplied_to);
    di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
    di->bat.properties = bq_bci_battery_props;
    di->bat.num_properties = ARRAY_SIZE(bq_bci_battery_props);
    di->bat.get_property = bq_bci_battery_get_property;
    di->bat_health = POWER_SUPPLY_HEALTH_GOOD;
    di->bat_exist = is_hisi_battery_exist();
    di->bat_err = 0;

    di->usb.name = "USB";
    di->usb.type = POWER_SUPPLY_TYPE_USB;
    di->usb.properties = bq_usb_props;
    di->usb.num_properties = ARRAY_SIZE(bq_usb_props);
    di->usb.get_property = bq_usb_get_property;
    di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;

    di->ac.name = "Mains";
    di->ac.type = POWER_SUPPLY_TYPE_MAINS;
    di->ac.properties = bq_ac_props;
    di->ac.num_properties = ARRAY_SIZE(bq_ac_props);
    di->ac.get_property = bq_ac_get_property;

    di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;

    di->bk_bat.name = "bq_bk_battery";
    di->bk_bat.type = POWER_SUPPLY_TYPE_UPS;
    di->bk_bat.properties = bq_bk_bci_battery_props;
    di->bk_bat.num_properties = ARRAY_SIZE(bq_bk_bci_battery_props);
    di->bk_bat.get_property = bq_bk_bci_battery_get_property;

    di->capacity = -1;
    di->capacity_filter_count = 0;
    di->charge_full_count = 0;

    for(i=0;i<WINDOW_LEN;i++) {
            capacity_filter[i] = hisi_battery_capacity();
            capacity_sum += capacity_filter[i];
    }

    bq_get_battery_info(di);

    platform_set_drvdata(pdev, di);

    wake_lock_init(&low_power_lock, WAKE_LOCK_SUSPEND, "low_power_wake_lock");

    low_bat_flag = is_hisi_battery_reach_threshold();
    if(( low_bat_flag & BQ27510_FLAG_LOCK ) == BQ27510_FLAG_LOCK) {
        wake_lock(&low_power_lock);
        is_low_power_locked = 1;
    }

    ret = power_supply_register(&pdev->dev, &di->bat);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register main battery\n");
        goto batt_failed;
    }

    ret = power_supply_register(&pdev->dev, &di->usb);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register usb power supply\n");
        goto usb_failed;
    }

    ret = power_supply_register(&pdev->dev, &di->ac);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register ac power supply\n");
        goto ac_failed;
    }

    ret = power_supply_register(&pdev->dev, &di->bk_bat);
    if (ret) {
        dev_dbg(&pdev->dev, "failed to register backup battery\n");
        goto bk_batt_failed;
    }

    INIT_DELAYED_WORK(&di->bq_bci_monitor_work,
                bq_bci_battery_work);
    schedule_delayed_work(&di->bq_bci_monitor_work, 0);

    di->nb.notifier_call = bq_charger_event;
    bq_register_notifier(&di->nb, 1);
    dev_err(&pdev->dev, "bq_bci probe ok!\n");

	if (!battery_dclient) {
		battery_dclient = dsm_register_client(&dsm_battery);
	}

    return 0;

bk_batt_failed:
    cancel_delayed_work(&di->bq_bci_monitor_work);
    power_supply_unregister(&di->ac);
ac_failed:
    power_supply_unregister(&di->usb);
usb_failed:
    power_supply_unregister(&di->bat);
batt_failed:
    wake_lock_destroy(&low_power_lock);
    platform_set_drvdata(pdev, NULL);
    kfree(di);
    di = NULL;
    return ret;
}
static int hi6401_irq_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct hi6401_irq *irq = NULL;
	enum of_gpio_flags flags;
	unsigned int virq;
	int ret = 0;
	int i;

	irq = devm_kzalloc(dev, sizeof(*irq), GFP_KERNEL);
	if (!irq) {
		dev_err(dev, "cannot allocate hi6401_irq device info\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, irq);

	/* get resources */
	irq->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!irq->res) {
		dev_err(dev, "platform_get_resource err\n");
		goto err_exit;
	}

	if (!devm_request_mem_region(dev, irq->res->start,
				     resource_size(irq->res),
				     pdev->name)) {
		dev_err(dev, "cannot claim register memory\n");
		goto err_exit;
	}

	irq->reg_base_addr = devm_ioremap(dev, irq->res->start,
					  resource_size(irq->res));
	if (!irq->reg_base_addr) {
		dev_err(dev, "cannot map register memory\n");
		goto ioremap_err;
	}


	/* get pinctrl */
	irq->pctrl = devm_pinctrl_get(dev);
	if (IS_ERR(irq->pctrl)) {
		dev_err(dev, "could not get pinctrl\n");
		goto codec_ssi_get_err;
	}
	ret = codec_ssi_iomux_default(irq->pctrl);
	if (0 != ret)
		goto codec_ssi_iomux_err;

	/* get codec ssi clk */
	irq->codec_ssi_clk = devm_clk_get(dev, "clk_codecssi");
	if (IS_ERR(irq->codec_ssi_clk)) {
		pr_err("clk_get: codecssi clk not found!\n");
		ret = PTR_ERR(irq->codec_ssi_clk);
		goto codec_ssi_clk_err;
	}
	ret = clk_prepare_enable(irq->codec_ssi_clk);
	if (0 != ret) {
		pr_err("codec_ssi_clk :clk prepare enable failed !\n");
		goto codec_ssi_clk_enable_err;
	}

	/* get pmu audio clk */
	irq->pmu_audio_clk = devm_clk_get(dev, "clk_pmuaudioclk");
	if (IS_ERR(irq->pmu_audio_clk)) {
		pr_err("_clk_get: pmu_audio_clk not found!\n");
		ret = PTR_ERR(irq->pmu_audio_clk);
		goto pmu_audio_clk_err;
	}
	ret = clk_prepare_enable(irq->pmu_audio_clk);
	if (0 != ret) {
		pr_err("pmu_audio_clk :clk prepare enable failed !\n");
		goto pmu_audio_clk_enable_err;
	}

	spin_lock_init(&irq->lock);
	spin_lock_init(&irq->rw_lock);
	mutex_init(&irq->sr_mutex);
	mutex_init(&irq->pll_mutex);
	wake_lock_init(&irq->wake_lock, WAKE_LOCK_SUSPEND, "hi6401-irq");

	irq->dev = dev;

	/* clear IRQ status */
	hi6401_irq_write(irq, HI6401_REG_IRQ_0, 0xFF);
	hi6401_irq_write(irq, HI6401_REG_IRQ_1, 0xFF);
	/* mask all irqs */
	hi6401_irq_write(irq, HI6401_REG_IRQM_0, 0xFF);
	hi6401_irq_write(irq, HI6401_REG_IRQM_1, 0xFF);

	irq->gpio = of_get_gpio_flags(np, 0, &flags);
	if (0 > irq->gpio) {
		dev_err(dev, "get gpio flags error\n");
		ret = irq->gpio;
		goto get_gpio_err;
	}

	if (!gpio_is_valid(irq->gpio)) {
		dev_err(dev, "gpio is invalid\n");
		ret = -EINVAL;
		goto get_gpio_err;
	}

	ret = gpio_request_one(irq->gpio, GPIOF_IN, "hi6401_irq");
	if (0 > ret) {
		dev_err(dev, "failed to request gpio%d\n", irq->gpio);
		goto get_gpio_err;
	}

	irq->irq = gpio_to_irq(irq->gpio);

	irq->domain = irq_domain_add_simple(np, HI6401_MAX_IRQS, 0,
					    &hi6401_domain_ops, irq);
	if (!irq->domain) {
		dev_err(dev, "irq domain error\n");
		ret = -ENODEV;
		goto gpio_err;
	}

	for (i = 0; i < HI6401_MAX_IRQS; i++) {
		virq = irq_create_mapping(irq->domain, i);
		if (virq == NO_IRQ) {
			dev_err(dev, "Failed mapping hwirq\n");
			ret = -ENOSPC;
			goto gpio_err;
		}
		irq->irqs[i] = virq;
	}

	ret = request_irq(irq->irq, hi6401_irq_handler,
				   IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND,
				   "hi6401_irq", irq);
	if (0 > ret) {
		dev_err(dev, "could not claim irq %d\n", ret);
		ret = -ENODEV;
		goto gpio_err;
	}
	irq->hi6401_irq_delay_wq = create_singlethread_workqueue("hi6401_irq_delay_wq");
	if (!(irq->hi6401_irq_delay_wq)) {
		pr_err("%s(%u) : workqueue create failed", __FUNCTION__,__LINE__);
		ret = -ENOMEM;
		goto irq_delay_wq_err;
	}
	INIT_DELAYED_WORK(&irq->hi6401_irq_delay_work, hi6401_irq_work_func);

	irq->pll_delay_wq = create_singlethread_workqueue("pll_delay_wq");
	if (!(irq->pll_delay_wq)) {
		pr_err("%s : pll_delay_wq create failed", __FUNCTION__);
		ret = -ENOMEM;
		goto pll_delay_wq_err;
	}
	INIT_DELAYED_WORK(&irq->pll_delay_work, hi6401_pll_work_func);

	g_dump_buf = (char*)kmalloc(sizeof(char)*Hi6401_SIZE_MAX, GFP_KERNEL);
	if (!g_dump_buf)
	{
		pr_err("%s : couldn't malloc buffer.\n",__FUNCTION__);
		ret = -ENOMEM;
		goto g_dump_buf_kmalloc_err;
	}
	memset(g_dump_buf, 0, Hi6401_SIZE_MAX);
	/* populate sub nodes */
	of_platform_populate(np, of_hi6401_irq_child_match_tbl, NULL, dev);

	if (!hi6401_client) {
		hi6401_client = dsm_register_client(&dsm_hi6401);
	}
	return 0;

g_dump_buf_kmalloc_err:
	if(irq->pll_delay_wq) {
		cancel_delayed_work(&irq->pll_delay_work);
		flush_workqueue(irq->pll_delay_wq);
		destroy_workqueue(irq->pll_delay_wq);
	}
pll_delay_wq_err:
	if(irq->hi6401_irq_delay_wq) {
		cancel_delayed_work(&irq->hi6401_irq_delay_work);
		flush_workqueue(irq->hi6401_irq_delay_wq);
		destroy_workqueue(irq->hi6401_irq_delay_wq);
	}
irq_delay_wq_err:
	free_irq(irq->irq, irq);
gpio_err:
	gpio_free(irq->gpio);
get_gpio_err:

	clk_disable_unprepare(irq->pmu_audio_clk);
pmu_audio_clk_enable_err:
	devm_clk_put(dev, irq->pmu_audio_clk);
pmu_audio_clk_err:
	clk_disable_unprepare(irq->codec_ssi_clk);
codec_ssi_clk_enable_err:
	devm_clk_put(dev, irq->codec_ssi_clk);
codec_ssi_clk_err:
	codec_ssi_iomux_idle(irq->pctrl);
codec_ssi_iomux_err:
	pinctrl_put(irq->pctrl);
codec_ssi_get_err:

	devm_iounmap(dev, irq->reg_base_addr);
ioremap_err:
	devm_release_mem_region(dev, irq->res->start,
				resource_size(irq->res));
err_exit:
	devm_kfree(dev, irq);

	return ret;
}
/*****************************************************************
Parameters    :  client
                 i2c_id
Return        :    
Description   :  call cyttsp5_probe in cyttsp5_core.c
*****************************************************************/
static int cyttsp5_i2c_probe(struct i2c_client *client,
	const struct i2c_device_id *i2c_id)
{
	struct device *dev = &client->dev;
#ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
	const struct of_device_id *match = NULL;
#endif
	int rc = 0;

	if(already_has_tp_driver_running()) {
		tp_log_warning("%s:  Another tp driver is running!\n",__func__);
		return 0;
	}

	tp_log_warning("%s %d:Probe start\n", __func__, __LINE__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		tp_log_err("%s %d:I2C functionality not Supported.\n", __func__, __LINE__);
		return -EIO;
	}

/* if support device tree, get pdata from device tree */
#ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
	match = of_match_device(of_match_ptr(cyttsp5_i2c_of_match), dev);
	if (match) {
		rc = cyttsp5_devtree_create_and_get_pdata(dev);
		if (rc < 0) {
			tp_log_err("%s %d:device tree create and get pdata fail, rc = %d.\n", 
						__func__, __LINE__, rc);
			return rc;
		}
	} else {
		tp_log_err("%s %d:No device mathced.\n", __func__, __LINE__);
		return -ENODEV;
	}
#endif

#ifdef CONFIG_HUAWEI_DSM
	tp_cyp_dclient = dsm_register_client(&dsm_cyp_tp);
	if (!tp_cyp_dclient)
		tp_log_err("%s: dsm register client failed\n", __func__);
#endif/*CONFIG_HUAWEI_DSM*/

	rc = cyttsp5_probe(&cyttsp5_i2c_bus_ops, &client->dev, client->irq,
			  CY_I2C_DATA_SIZE);

#ifdef CONFIG_TOUCHSCREEN_CYPRESS_CYTTSP5_DEVICETREE_SUPPORT
	if (rc && match) {
		cyttsp5_devtree_clean_pdata(dev);
#ifdef CONFIG_HUAWEI_DSM
		if (tp_cyp_dclient) {
			dsm_unregister_client(tp_cyp_dclient, &dsm_cyp_tp);
			tp_cyp_dclient = NULL;
		}
#endif/*CONFIG_HUAWEI_DSM*/
		tp_log_err("%s %d:cyttsp5 probe fail.\n", __func__, __LINE__);
		return rc;
	}
#endif

	set_tp_driver_running();
	tp_log_info("%s %d:cyttsp5 probe success.\n", __func__, __LINE__);

	return rc;
}