Example #1
0
static int __devinit smsc_hub_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct smsc_hub_platform_data *pdata;
	struct device_node *node = pdev->dev.of_node;
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;
	struct of_dev_auxdata *hsic_host_auxdata = NULL;

	if (pdev->dev.of_node) {
		dev_dbg(&pdev->dev, "device tree enabled\n");
		hsic_host_auxdata = dev_get_platdata(&pdev->dev);
		pdata = msm_hub_dt_to_pdata(pdev);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);
	} else {
		pdata = pdev->dev.platform_data;
	}

	if (!pdata) {
		dev_err(&pdev->dev, "No platform data\n");
		return -ENODEV;
	}

	if (!pdata->hub_reset)
		return -EINVAL;

	smsc_hub = devm_kzalloc(&pdev->dev, sizeof(*smsc_hub), GFP_KERNEL);
	if (!smsc_hub)
		return -ENOMEM;

	smsc_hub->dev = &pdev->dev;
	smsc_hub->pdata = pdata;

	smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub_vbus");
	ret = PTR_ERR(smsc_hub->hub_vbus_reg);
	if (ret == -EPROBE_DEFER) {
		dev_dbg(&pdev->dev, "failed to get hub_vbus\n");
		return ret;
	}

	ret = msm_hsic_hub_init_vdd(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub VDD\n");
		return ret;
	}
	ret = msm_hsic_hub_init_clock(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub clock\n");
		goto uninit_vdd;
	}
	ret = msm_hsic_hub_init_gpio(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub gpios\n");
		goto uninit_clock;
	}

	gpio_direction_output(pdata->hub_reset, 0);
	/*
	 * Hub reset should be asserted for minimum 2microsec
	 * before deasserting.
	 */
	udelay(5);
	gpio_direction_output(pdata->hub_reset, 1);

	if (!IS_ERR(smsc_hub->hub_vbus_reg)) {
		ret = regulator_enable(smsc_hub->hub_vbus_reg);
		if (ret) {
			dev_err(&pdev->dev, "unable to enable hub_vbus\n");
			goto uninit_gpio;
		}
	}

	ret = i2c_add_driver(&hsic_hub_driver);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n");
		goto i2c_add_fail;
	}
	usleep_range(10000, 12000);
	i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID);

	if (!i2c_adap) {
		dev_err(&pdev->dev, "failed to get i2c adapter\n");
		i2c_del_driver(&hsic_hub_driver);
		goto i2c_add_fail;
	}

	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE);

	/* 250ms delay is required for SMSC4604 HUB to get I2C up */
	msleep(250);

	/* Assign I2C slave address per SMSC model */
	switch (pdata->model_id) {
	case SMSC3503_ID:
		normal_i2c[0] = SMSC3503_I2C_ADDR;
		break;
	case SMSC4604_ID:
		normal_i2c[0] = SMSC4604_I2C_ADDR;
		break;
	default:
		dev_err(&pdev->dev, "unsupported SMSC model-id\n");
		i2c_put_adapter(i2c_adap);
		i2c_del_driver(&hsic_hub_driver);
		goto uninit_gpio;
	}

	smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c, NULL);
	i2c_put_adapter(i2c_adap);

i2c_add_fail:
	ret = of_platform_populate(node, NULL, hsic_host_auxdata, &pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret);
		goto uninit_gpio;
	}

	if (!smsc_hub->client)
		dev_err(&pdev->dev,
			"failed to connect to smsc_hub through I2C\n");

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

uninit_gpio:
	msm_hsic_hub_init_gpio(smsc_hub, 0);
uninit_clock:
	msm_hsic_hub_init_clock(smsc_hub, 0);
uninit_vdd:
	msm_hsic_hub_init_vdd(smsc_hub, 0);

	return ret;
}
Example #2
0
static int __devinit smsc_hub_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct smsc_hub_platform_data *pdata;
	struct device_node *node = pdev->dev.of_node;
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;
	struct of_dev_auxdata *hsic_host_auxdata = NULL;

	if (pdev->dev.of_node) {
		dev_dbg(&pdev->dev, "device tree enabled\n");
		pdata = msm_hub_dt_to_pdata(pdev);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);
	} else {
		pdata = pdev->dev.platform_data;
	}
	hsic_host_auxdata = dev_get_platdata(&pdev->dev);

	if (!pdata) {
		dev_err(&pdev->dev, "No platform data\n");
		return -ENODEV;
	}

	if (pdata->model_id == 0) {
		dev_dbg(&pdev->dev, "standalone HSIC config enabled\n");
		return of_platform_populate(node, NULL,
				hsic_host_auxdata, &pdev->dev);
	}

	if (!pdata->hub_reset)
		return -EINVAL;

	smsc_hub = devm_kzalloc(&pdev->dev, sizeof(*smsc_hub), GFP_KERNEL);
	if (!smsc_hub)
		return -ENOMEM;

	smsc_hub->dev = &pdev->dev;
	smsc_hub->pdata = pdata;

	if (of_get_property(pdev->dev.of_node, "hub-vbus-supply", NULL)) {
		smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev,
				"hub-vbus");
		ret = PTR_ERR(smsc_hub->hub_vbus_reg);
		if (ret == -EPROBE_DEFER) {
			dev_dbg(&pdev->dev, "failed to get hub_vbus\n");
			return ret;
		}
	}

	ret = msm_hsic_hub_init_vdd(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub VDD\n");
		return ret;
	}
	ret = msm_hsic_hub_init_clock(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub clock\n");
		goto uninit_vdd;
	}
	ret = msm_hsic_hub_init_gpio(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub gpios\n");
		goto uninit_clock;
	}

	if (pdata->model_id == SMSC3502_ID) {
		ret = device_create_file(&pdev->dev, &dev_attr_enable);
		if (ret < 0) {
			dev_err(&pdev->dev, "fail to create sysfs file\n");
			goto uninit_gpio;
		}
		pm_runtime_forbid(&pdev->dev);
		goto done;
	}

	gpio_direction_output(pdata->hub_reset, 0);
	udelay(5);
	gpio_direction_output(pdata->hub_reset, 1);

	if (!IS_ERR_OR_NULL(smsc_hub->hub_vbus_reg)) {
		ret = regulator_enable(smsc_hub->hub_vbus_reg);
		if (ret) {
			dev_err(&pdev->dev, "unable to enable hub_vbus\n");
			goto uninit_gpio;
		}
	}

	ret = i2c_add_driver(&hsic_hub_driver);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n");
		goto i2c_add_fail;
	}
	usleep_range(10000, 12000);
	i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID);

	if (!i2c_adap) {
		dev_err(&pdev->dev, "failed to get i2c adapter\n");
		i2c_del_driver(&hsic_hub_driver);
		goto i2c_add_fail;
	}

	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE);

	
	msleep(250);

	
	switch (pdata->model_id) {
	case SMSC3503_ID:
		normal_i2c[0] = SMSC3503_I2C_ADDR;
		break;
	case SMSC4604_ID:
		normal_i2c[0] = SMSC4604_I2C_ADDR;
		break;
	default:
		dev_err(&pdev->dev, "unsupported SMSC model-id\n");
		i2c_put_adapter(i2c_adap);
		i2c_del_driver(&hsic_hub_driver);
		goto uninit_gpio;
	}

	smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c, NULL);
	i2c_put_adapter(i2c_adap);

i2c_add_fail:
	ret = of_platform_populate(node, NULL, hsic_host_auxdata, &pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret);
		goto uninit_gpio;
	}

	smsc_hub->enabled = true;

	if (!smsc_hub->client)
		dev_err(&pdev->dev,
			"failed to connect to smsc_hub through I2C\n");

done:
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

uninit_gpio:
	msm_hsic_hub_init_gpio(smsc_hub, 0);
uninit_clock:
	msm_hsic_hub_init_clock(smsc_hub, 0);
uninit_vdd:
	msm_hsic_hub_init_vdd(smsc_hub, 0);

	return ret;
}
Example #3
0
static int __devinit smsc_hub_probe(struct platform_device *pdev)
{
	int ret = 0;
	const struct smsc_hub_platform_data *pdata;
	struct device_node *node = pdev->dev.of_node;
	struct i2c_adapter *i2c_adap;
	struct i2c_board_info i2c_info;

	if (pdev->dev.of_node) {
		dev_dbg(&pdev->dev, "device tree enabled\n");
		pdev->dev.platform_data = msm_hub_dt_to_pdata(pdev);
		if (IS_ERR(pdev->dev.platform_data))
			return PTR_ERR(pdev->dev.platform_data);

		dev_set_name(&pdev->dev, smsc_hub_driver.driver.name);
	}

	if (!pdev->dev.platform_data) {
		dev_err(&pdev->dev, "No platform data\n");
		return -ENODEV;
	}

	pdata = pdev->dev.platform_data;
	if (!pdata->hub_reset)
		return -EINVAL;

	smsc_hub = devm_kzalloc(&pdev->dev, sizeof(*smsc_hub), GFP_KERNEL);
	if (!smsc_hub)
		return -ENOMEM;

	smsc_hub->dev = &pdev->dev;
	smsc_hub->pdata = pdev->dev.platform_data;

	smsc_hub->hub_vbus_reg = devm_regulator_get(&pdev->dev, "hub_vbus");
	ret = PTR_ERR(smsc_hub->hub_vbus_reg);
	if (ret == -EPROBE_DEFER) {
		dev_dbg(&pdev->dev, "failed to get hub_vbus\n");
		return ret;
	}

	ret = msm_hsic_hub_init_vdd(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub VDD\n");
		return ret;
	}
	ret = msm_hsic_hub_init_clock(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub clock\n");
		goto uninit_vdd;
	}
	ret = msm_hsic_hub_init_gpio(smsc_hub, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to init hub gpios\n");
		goto uninit_clock;
	}

	gpio_direction_output(pdata->hub_reset, 0);
	/* Hub reset should be asserted for minimum 2microsec
	 * before deasserting.
	 */
	udelay(5);
	gpio_direction_output(pdata->hub_reset, 1);

	ret = of_platform_populate(node, NULL, NULL, &pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to add child node, ret=%d\n", ret);
		goto uninit_gpio;
	}

	if (!IS_ERR(smsc_hub->hub_vbus_reg)) {
		ret = regulator_enable(smsc_hub->hub_vbus_reg);
		if (ret) {
			dev_err(&pdev->dev, "unable to enable hub_vbus\n");
			goto uninit_gpio;
		}
	}

	ret = i2c_add_driver(&hsic_hub_driver);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to add I2C hsic_hub_driver\n");
		goto i2c_add_fail;
	}
	usleep_range(10000, 12000);
	i2c_adap = i2c_get_adapter(SMSC_GSBI_I2C_BUS_ID);

	if (!i2c_adap) {
		dev_err(&pdev->dev, "failed to get i2c adapter\n");
		i2c_del_driver(&hsic_hub_driver);
		goto i2c_add_fail;
	}

	memset(&i2c_info, 0, sizeof(struct i2c_board_info));
	strlcpy(i2c_info.type, "i2c_hsic_hub", I2C_NAME_SIZE);

	smsc_hub->client = i2c_new_probed_device(i2c_adap, &i2c_info,
						   normal_i2c, NULL);
	i2c_put_adapter(i2c_adap);
	if (!smsc_hub->client)
		dev_err(&pdev->dev, "failed to connect to smsc_hub"
			 "through I2C\n");

i2c_add_fail:
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

	return 0;

uninit_gpio:
	msm_hsic_hub_init_gpio(smsc_hub, 0);
uninit_clock:
	msm_hsic_hub_init_clock(smsc_hub, 0);
uninit_vdd:
	msm_hsic_hub_init_vdd(smsc_hub, 0);

	return ret;
}