コード例 #1
0
static int twl6030_usb_probe(struct platform_device *pdev)
{
	u32 ret;
	struct twl6030_usb	*twl;
	int			status, err;
	struct device_node	*np = pdev->dev.of_node;
	struct device		*dev = &pdev->dev;
	struct twl4030_usb_data	*pdata = dev->platform_data;

	twl = devm_kzalloc(dev, sizeof *twl, GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	twl->dev		= &pdev->dev;
	twl->irq1		= platform_get_irq(pdev, 0);
	twl->irq2		= platform_get_irq(pdev, 1);
	twl->linkstat		= OMAP_MUSB_UNKNOWN;

	twl->comparator.set_vbus	= twl6030_set_vbus;
	twl->comparator.start_srp	= twl6030_start_srp;

	ret = omap_usb2_set_comparator(&twl->comparator);
	if (ret == -ENODEV) {
		dev_info(&pdev->dev, "phy not ready, deferring probe");
		return -EPROBE_DEFER;
	}

	if (np) {
		twl->regulator = "usb";
	} else if (pdata) {
		if (pdata->features & TWL6025_SUBCLASS)
			twl->regulator = "ldousb";
		else
			twl->regulator = "vusb";
	} else {
		dev_err(&pdev->dev, "twl6030 initialized without pdata\n");
		return -EINVAL;
	}

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl6030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		return err;
	}

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);

	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq1, status);
		device_remove_file(twl->dev, &dev_attr_vbus);
		return status;
	}

	status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq2, status);
		free_irq(twl->irq1, twl);
		device_remove_file(twl->dev, &dev_attr_vbus);
		return status;
	}

	twl->asleep = 0;
	twl6030_enable_irq(twl);
	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");

	return 0;
}
コード例 #2
0
ファイル: qt1070.c プロジェクト: 125radheyshyam/linux
static int __devinit qt1070_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct qt1070_data *data;
	struct input_dev *input;
	int i;
	int err;

	err = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
	if (!err) {
		dev_err(&client->dev, "%s adapter not supported\n",
			dev_driver_string(&client->adapter->dev));
		return -ENODEV;
	}

	if (!client->irq) {
		dev_err(&client->dev, "please assign the irq to this device\n");
		return -EINVAL;
	}

	/* Identify the qt1070 chip */
	if (!qt1070_identify(client))
		return -ENODEV;

	data = kzalloc(sizeof(struct qt1070_data), GFP_KERNEL);
	input = input_allocate_device();
	if (!data || !input) {
		dev_err(&client->dev, "insufficient memory\n");
		err = -ENOMEM;
		goto err_free_mem;
	}

	data->client = client;
	data->input = input;
	data->irq = client->irq;

	input->name = "AT42QT1070 QTouch Sensor";
	input->dev.parent = &client->dev;
	input->id.bustype = BUS_I2C;

	/* Add the keycode */
	input->keycode = data->keycodes;
	input->keycodesize = sizeof(data->keycodes[0]);
	input->keycodemax = ARRAY_SIZE(qt1070_key2code);

	__set_bit(EV_KEY, input->evbit);

	for (i = 0; i < ARRAY_SIZE(qt1070_key2code); i++) {
		data->keycodes[i] = qt1070_key2code[i];
		__set_bit(qt1070_key2code[i], input->keybit);
	}

	/* Calibrate device */
	qt1070_write(client, CALIBRATE_CMD, 1);
	msleep(QT1070_CAL_TIME);

	/* Soft reset */
	qt1070_write(client, RESET, 1);
	msleep(QT1070_RESET_TIME);

	err = request_threaded_irq(client->irq, NULL, qt1070_interrupt,
		IRQF_TRIGGER_NONE, client->dev.driver->name, data);
	if (err) {
		dev_err(&client->dev, "fail to request irq\n");
		goto err_free_mem;
	}

	/* Register the input device */
	err = input_register_device(data->input);
	if (err) {
		dev_err(&client->dev, "Failed to register input device\n");
		goto err_free_irq;
	}

	i2c_set_clientdata(client, data);

	/* Read to clear the chang line */
	qt1070_read(client, DET_STATUS);

	return 0;

err_free_irq:
	free_irq(client->irq, data);
err_free_mem:
	input_free_device(input);
	kfree(data);
	return err;
}
コード例 #3
0
ファイル: tegra-otg.c プロジェクト: mdeejay/picasso-hc-kernel
static int tegra_otg_probe(struct platform_device *pdev)
{
	struct tegra_otg_data *tegra;
	struct resource *res;
	int err;

	tegra = kzalloc(sizeof(struct tegra_otg_data), GFP_KERNEL);
	if (!tegra)
		return -ENOMEM;

	tegra->otg.dev = &pdev->dev;
	tegra->otg.label = "tegra-otg";
	tegra->otg.state = OTG_STATE_UNDEFINED;
	tegra->otg.set_host = tegra_otg_set_host;
	tegra->otg.set_peripheral = tegra_otg_set_peripheral;
	tegra->otg.set_suspend = tegra_otg_set_suspend;
	tegra->otg.set_power = tegra_otg_set_power;
	spin_lock_init(&tegra->lock);
        wake_lock_init(&usb_wake_lock, WAKE_LOCK_SUSPEND, "tegra_otg");

	platform_set_drvdata(pdev, tegra);

	tegra->clk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(tegra->clk)) {
		dev_err(&pdev->dev, "Can't get otg clock\n");
		err = PTR_ERR(tegra->clk);
		goto err_clk;
	}

	err = clk_enable(tegra->clk);
	if (err)
		goto err_clken;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get I/O memory\n");
		err = -ENXIO;
		goto err_io;
	}
	tegra->regs = ioremap(res->start, resource_size(res));
	if (!tegra->regs) {
		err = -ENOMEM;
		goto err_io;
	}

	tegra->otg.state = OTG_STATE_A_SUSPEND;

	err = otg_set_transceiver(&tegra->otg);
	if (err) {
		dev_err(&pdev->dev, "can't register transceiver (%d)\n", err);
		goto err_otg;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get IRQ\n");
		err = -ENXIO;
		goto err_irq;
	}
	tegra->irq = res->start;
	err = request_threaded_irq(tegra->irq, tegra_otg_irq,
				   NULL,
				   IRQF_SHARED, "tegra-otg", tegra);
	if (err) {
		dev_err(&pdev->dev, "Failed to register IRQ\n");
		goto err_irq;
	}
	INIT_WORK (&tegra->work, irq_work);

	dev_info(&pdev->dev, "otg transceiver registered\n");
	return 0;

err_irq:
	otg_set_transceiver(NULL);
err_otg:
	iounmap(tegra->regs);
err_io:
	clk_disable(tegra->clk);
err_clken:
	clk_put(tegra->clk);
err_clk:
	platform_set_drvdata(pdev, NULL);
	kfree(tegra);
	return err;
}
コード例 #4
0
static int __devinit isl29028_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct isl29028_chip *chip;
	int err;
	struct iio_dev *indio_dev;
	indio_dev = iio_allocate_device(sizeof(*chip));
	if (indio_dev == NULL) {
		dev_err(&client->dev, "Memory allocation fails\n");
		err =  -ENOMEM;
		goto exit;
	}
	chip = iio_priv(indio_dev);

	dev_dbg(&client->dev, "%s() called\n", __func__);

	i2c_set_clientdata(client, chip);
	chip->client = client;
	chip->irq = client->irq;

	mutex_init(&chip->lock);

	err = isl29028_chip_init(client);
	if (err)
		goto exit_free;

	init_completion(&chip->prox_completion);
	init_completion(&chip->als_completion);

	if (chip->irq > 0) {
		err = request_threaded_irq(chip->irq, NULL, threshold_isr,
						IRQF_SHARED, "ISL29028", chip);
		if (err) {
			dev_err(&client->dev, "Unable to register irq %d; "
				"error %d\n", chip->irq, err);
			goto exit_free;
		}
	}

	chip->is_int_enable = true;

	indio_dev->name = id->name;
	indio_dev->info = &isl29028_info;
	indio_dev->dev.parent = &client->dev;
	indio_dev->modes = INDIO_DIRECT_MODE;
	err = iio_device_register(indio_dev);
	if (err) {
		dev_err(&client->dev, "iio registration fails\n");
		goto exit_irq;
	}
	dev_dbg(&client->dev, "%s() success\n", __func__);
	return 0;

exit_irq:
	if (chip->irq > 0)
		free_irq(chip->irq, chip);
exit_free:
	iio_free_device(indio_dev);
exit:
	return err;
}
コード例 #5
0
ファイル: pci-me.c プロジェクト: mobilehunter/trafficsqueezer
/**
 * mei_me_probe - Device Initialization Routine
 *
 * @pdev: PCI device structure
 * @ent: entry in kcs_pci_tbl
 *
 * Return: 0 on success, <0 on failure.
 */
static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data);
	struct mei_device *dev;
	struct mei_me_hw *hw;
	int err;


	if (!mei_me_quirk_probe(pdev, cfg))
		return -ENODEV;

	/* enable pci dev */
	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "failed to enable pci device.\n");
		goto end;
	}
	/* set PCI host mastering  */
	pci_set_master(pdev);
	/* pci request regions for mei driver */
	err = pci_request_regions(pdev, KBUILD_MODNAME);
	if (err) {
		dev_err(&pdev->dev, "failed to get pci regions.\n");
		goto disable_device;
	}

	if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) ||
	    dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {

		err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
		if (err)
			err = dma_set_coherent_mask(&pdev->dev,
						    DMA_BIT_MASK(32));
	}
	if (err) {
		dev_err(&pdev->dev, "No usable DMA configuration, aborting\n");
		goto release_regions;
	}


	/* allocates and initializes the mei dev structure */
	dev = mei_me_dev_init(pdev, cfg);
	if (!dev) {
		err = -ENOMEM;
		goto release_regions;
	}
	hw = to_me_hw(dev);
	/* mapping  IO device memory */
	hw->mem_addr = pci_iomap(pdev, 0, 0);
	if (!hw->mem_addr) {
		dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
		err = -ENOMEM;
		goto free_device;
	}
	if (!disable_msi)
		pci_enable_msi(pdev);

	 /* request and enable interrupt */
	if (pci_dev_msi_enabled(pdev))
		err = request_threaded_irq(pdev->irq,
			NULL,
			mei_me_irq_thread_handler,
			IRQF_ONESHOT, KBUILD_MODNAME, dev);
	else
		err = request_threaded_irq(pdev->irq,
			mei_me_irq_quick_handler,
			mei_me_irq_thread_handler,
			IRQF_SHARED, KBUILD_MODNAME, dev);

	if (err) {
		dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
		       pdev->irq);
		goto disable_msi;
	}

	if (mei_start(dev)) {
		dev_err(&pdev->dev, "init hw failure.\n");
		err = -ENODEV;
		goto release_irq;
	}

	pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_ME_RPM_TIMEOUT);
	pm_runtime_use_autosuspend(&pdev->dev);

	err = mei_register(dev, &pdev->dev);
	if (err)
		goto release_irq;

	pci_set_drvdata(pdev, dev);

	schedule_delayed_work(&dev->timer_work, HZ);

	/*
	* For not wake-able HW runtime pm framework
	* can't be used on pci device level.
	* Use domain runtime pm callbacks instead.
	*/
	if (!pci_dev_run_wake(pdev))
		mei_me_set_pm_domain(dev);

	if (mei_pg_is_enabled(dev))
		pm_runtime_put_noidle(&pdev->dev);

	dev_dbg(&pdev->dev, "initialization successful.\n");

	return 0;

release_irq:
	mei_cancel_work(dev);
	mei_disable_interrupts(dev);
	free_irq(pdev->irq, dev);
disable_msi:
	pci_disable_msi(pdev);
	pci_iounmap(pdev, hw->mem_addr);
free_device:
	kfree(dev);
release_regions:
	pci_release_regions(pdev);
disable_device:
	pci_disable_device(pdev);
end:
	dev_err(&pdev->dev, "initialization failed.\n");
	return err;
}
コード例 #6
0
ファイル: tc3589x-keypad.c プロジェクト: ultraembedded/linux
static int tc3589x_keypad_probe(struct platform_device *pdev)
{
    struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
    struct tc_keypad *keypad;
    struct input_dev *input;
    const struct tc3589x_keypad_platform_data *plat;
    int error, irq;

    plat = tc3589x->pdata->keypad;
    if (!plat) {
        dev_err(&pdev->dev, "invalid keypad platform data\n");
        return -EINVAL;
    }

    irq = platform_get_irq(pdev, 0);
    if (irq < 0)
        return irq;

    keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL);
    input = input_allocate_device();
    if (!keypad || !input) {
        dev_err(&pdev->dev, "failed to allocate keypad memory\n");
        error = -ENOMEM;
        goto err_free_mem;
    }

    keypad->board = plat;
    keypad->input = input;
    keypad->tc3589x = tc3589x;

    input->id.bustype = BUS_I2C;
    input->name = pdev->name;
    input->dev.parent = &pdev->dev;

    input->open = tc3589x_keypad_open;
    input->close = tc3589x_keypad_close;

    error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
                                       TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL,
                                       NULL, input);
    if (error) {
        dev_err(&pdev->dev, "Failed to build keymap\n");
        goto err_free_mem;
    }

    keypad->keymap = input->keycode;

    input_set_capability(input, EV_MSC, MSC_SCAN);
    if (!plat->no_autorepeat)
        __set_bit(EV_REP, input->evbit);

    input_set_drvdata(input, keypad);

    error = request_threaded_irq(irq, NULL,
                                 tc3589x_keypad_irq, plat->irqtype,
                                 "tc3589x-keypad", keypad);
    if (error < 0) {
        dev_err(&pdev->dev,
                "Could not allocate irq %d,error %d\n",
                irq, error);
        goto err_free_mem;
    }

    error = input_register_device(input);
    if (error) {
        dev_err(&pdev->dev, "Could not register input device\n");
        goto err_free_irq;
    }

    /* let platform decide if keypad is a wakeup source or not */
    device_init_wakeup(&pdev->dev, plat->enable_wakeup);
    device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup);

    platform_set_drvdata(pdev, keypad);

    return 0;

err_free_irq:
    free_irq(irq, keypad);
err_free_mem:
    input_free_device(input);
    kfree(keypad);
    return error;
}
コード例 #7
0
ファイル: slimport.c プロジェクト: Defector/Defkernel_F320
static int anx7808_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{

	struct anx7808_data *anx7808;
	struct anx7808_platform_data *pdata;
	int ret = 0;
	int sbl_cable_type = 0;

#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 anx7808\n", __func__);
		ret = -ENODEV;
		goto exit;
	}

	anx7808 = kzalloc(sizeof(struct anx7808_data), GFP_KERNEL);
	if (!anx7808) {
		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 anx7808_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 = anx7808_parse_dt(&client->dev, pdata);
		if (ret != 0) /* if occurs error */
			goto err0;

		anx7808->pdata = pdata;
	} else {
		anx7808->pdata = client->dev.platform_data;
	}

	/* to access global platform data */
	g_pdata = anx7808->pdata;

	anx7808_client = client;

	mutex_init(&anx7808->lock);

	if (!anx7808->pdata) {
		ret = -EINVAL;
		goto err0;
	}

	ret = anx7808_init_gpio(anx7808);
	if (ret) {
		pr_err("%s: failed to initialize gpio\n", __func__);
		goto err0;
	}

	INIT_DELAYED_WORK(&anx7808->work, anx7808_work_func);
	//INIT_DELAYED_WORK(&anx7808->dwc3_ref_clk_work, dwc3_ref_clk_work_func);

	anx7808->workqueue = create_singlethread_workqueue("anx7808_work");
	if (anx7808->workqueue == NULL) {
		pr_err("%s: failed to create work queue\n", __func__);
		ret = -ENOMEM;
		goto err1;
	}

	anx7808->pdata->avdd_power(1);
	anx7808->pdata->dvdd_power(1);

	ret = anx7808_system_init();
	if (ret) {
		pr_err("%s: failed to initialize anx7808\n", __func__);
		goto err2;
	}

	client->irq = gpio_to_irq(anx7808->pdata->gpio_cbl_det);
	if (client->irq < 0) {
		pr_err("%s : failed to get gpio irq\n", __func__);
		goto err2;
	}

	wake_lock_init(&anx7808->slimport_lock,
				WAKE_LOCK_SUSPEND,
				"slimport_wake_lock");

	sbl_cable_type = anx7808_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, anx7808_cbl_det_isr,
						IRQF_TRIGGER_RISING
						| IRQF_TRIGGER_FALLING
						| IRQF_ONESHOT,
						"anx7808", anx7808);
		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 (anx7808->pdata->hdmi_pdev) {
		ret = msm_hdmi_register_slimport(anx7808->pdata->hdmi_pdev,
					   hdmi_slimport_ops, anx7808);
		if (ret) {
			pr_err("%s: register with hdmi failed\n", __func__);
			ret = -EPROBE_DEFER;
			goto err3;
		}
	}
#endif

	goto exit;

err3:
	free_irq(client->irq, anx7808);
err2:
	destroy_workqueue(anx7808->workqueue);
err1:
	anx7808_free_gpio(anx7808);
err0:
	anx7808_client = NULL;
	kfree(anx7808);
exit:
	return ret;
}
コード例 #8
0
ファイル: twl4030-usb.c プロジェクト: Adjustxx/Savaged-Zen
static int __devinit twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
	struct twl4030_usb	*twl;
	int			status, err;

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

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

	twl->dev		= &pdev->dev;
	twl->irq		= platform_get_irq(pdev, 0);
	twl->otg.dev		= twl->dev;
	twl->otg.label		= "twl4030";
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;
	twl->usb_mode		= pdata->usb_mode;
	twl->asleep = 1;

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl4030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(twl);
		return err;
	}
	otg_set_transceiver(&twl->otg);

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);

	/* Our job is to use irqs and status from the power module
	 * to keep the transceiver disabled when nothing's connected.
	 *
	 * FIXME we actually shouldn't start enabling it until the
	 * USB controller drivers have said they're ready, by calling
	 * set_host() and/or set_peripheral() ... OTG_capable boards
	 * need both handles, otherwise just one suffices.
	 */
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl4030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return status;
	}

	/* Power down phy or make it work according to
	 * current link state.
	 */
	twl4030_usb_phy_init(twl);

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
コード例 #9
0
static int __devinit mipi_samsung_disp_probe(struct platform_device *pdev)
{

	struct platform_device *msm_fb_added_dev;
#if defined(CONFIG_LCD_CLASS_DEVICE)
	struct lcd_device *lcd_device;
	int ret;
#endif
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE)
	struct backlight_device *bd;
#endif
	msd.dstat.acl_on = false;

	if (pdev->id == 0) {
		msd.mipi_samsung_disp_pdata = pdev->dev.platform_data;

		first_on = false;
		return 0;
	}

	msm_fb_added_dev = msm_fb_add_device(pdev);

	mutex_init(&dsi_tx_mutex);

#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_LCD_CLASS_DEVICE)
	msd.msm_pdev = msm_fb_added_dev;
#endif

#if defined(CONFIG_HAS_EARLYSUSPEND)
	msd.early_suspend.suspend = mipi_samsung_disp_early_suspend;
	msd.early_suspend.resume = mipi_samsung_disp_late_resume;
	msd.early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
	register_early_suspend(&msd.early_suspend);

#endif

#if defined(CONFIG_ESD_ERR_FG_RECOVERY)
	INIT_WORK(&err_fg_work, err_fg_work_func);

	err_fg_gpio = MSM_GPIO_TO_INT(GPIO_ESD_VGH_DET);

	ret = gpio_request(GPIO_ESD_VGH_DET, "err_fg");
	if (ret) {
		pr_err("request gpio GPIO_LCD_ESD_DET failed, ret=%d\n",ret);
		gpio_free(GPIO_ESD_VGH_DET);
		return ret;
	}

	gpio_tlmm_config(GPIO_CFG(GPIO_ESD_VGH_DET,  0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),GPIO_CFG_ENABLE);

	ret = request_threaded_irq(err_fg_gpio, NULL, err_fg_irq_handler, 
		IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "esd_detect", NULL);
	if (ret) {
		pr_err("%s : Failed to request_irq. :ret=%d", __func__, ret);
	}

	disable_irq(err_fg_gpio);
#endif

#if defined(CONFIG_LCD_CLASS_DEVICE)
	lcd_device = lcd_device_register("panel", &pdev->dev, NULL,
					&mipi_samsung_disp_props);

	if (IS_ERR(lcd_device)) {
		ret = PTR_ERR(lcd_device);
		printk(KERN_ERR "lcd : failed to register device\n");
		return ret;
	}

#ifdef WA_FOR_FACTORY_MODE
	sysfs_remove_file(&lcd_device->dev.kobj,
					&dev_attr_lcd_power.attr);

	ret = sysfs_create_file(&lcd_device->dev.kobj,
					&dev_attr_lcd_power.attr);
	if (ret) {
		pr_info("sysfs create fail-%s\n",
				dev_attr_lcd_power.attr.name);
	}
#endif

	ret = sysfs_create_file(&lcd_device->dev.kobj,
					&dev_attr_lcd_type.attr);
	if (ret) {
		pr_info("sysfs create fail-%s\n",
				dev_attr_lcd_type.attr.name);
	}

	ret = sysfs_create_file(&lcd_device->dev.kobj,
					&dev_attr_gamma_mode.attr);
	if (ret) {
		pr_info("sysfs create fail-%s\n",
				dev_attr_gamma_mode.attr.name);
	}

	ret = sysfs_create_file(&lcd_device->dev.kobj,
					&dev_attr_power_reduce.attr);
	if (ret) {
		pr_info("sysfs create fail-%s\n",
				dev_attr_power_reduce.attr.name);
	}
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE)
	bd = backlight_device_register("panel", &lcd_device->dev,
						NULL, NULL, NULL);
	if (IS_ERR(bd)) {
		ret = PTR_ERR(bd);
		pr_info("backlight : failed to register device\n");
		return ret;
	}

	ret = sysfs_create_file(&bd->dev.kobj,
					&dev_attr_auto_brightness.attr);
	if (ret) {
		pr_info("sysfs create fail-%s\n",
				dev_attr_auto_brightness.attr.name);
	}
#endif
#endif
#if defined(CONFIG_MDNIE_LITE_TUNING) \
	|| defined(CONFIG_FB_MDP4_ENHANCE)
	/*	mdnie sysfs create */
	init_mdnie_class();
#endif

	mipi_dsi_buf_alloc(&mdnie_tune_tx_buf, DSI_BUF_SIZE);

#if defined(DDI_VIDEO_ENHANCE_TUNING)
	ret = sysfs_create_file(&lcd_device->dev.kobj,
				&dev_attr_tuning.attr);
	if (ret) {
		pr_info("sysfs create fail-%s\n",
				dev_attr_tuning.attr.name);
	}
#endif

	return 0;
}
コード例 #10
0
ファイル: retu-headset.c プロジェクト: JamesAng/lx-sk
static int __init retu_headset_probe(struct platform_device *pdev)
{
	struct retu_headset *hs;
	int irq;
	int r;

	hs = kzalloc(sizeof(*hs), GFP_KERNEL);
	if (hs == NULL)
		return -ENOMEM;

	hs->dev = &pdev->dev;

	hs->idev = input_allocate_device();
	if (hs->idev == NULL) {
		r = -ENOMEM;
		goto err1;
	}
	hs->idev->name = "retu-headset";
	hs->idev->dev.parent = &pdev->dev;
	set_bit(EV_KEY, hs->idev->evbit);
	set_bit(RETU_HEADSET_KEY, hs->idev->keybit);
	r = input_register_device(hs->idev);
	if (r < 0)
		goto err2;

	r = device_create_file(&pdev->dev, &dev_attr_hookdet);
	if (r < 0)
		goto err3;
	r = device_create_file(&pdev->dev, &dev_attr_enable);
	if (r < 0)
		goto err4;
	r = device_create_file(&pdev->dev, &dev_attr_enable_det);
	if (r < 0)
		goto err5;
	platform_set_drvdata(pdev, hs);

	spin_lock_init(&hs->lock);
	mutex_init(&hs->mutex);
	setup_timer(&hs->enable_timer, retu_headset_enable_timer,
		    (unsigned long) hs);
	setup_timer(&hs->detect_timer, retu_headset_detect_timer,
		    (unsigned long) hs);

	irq = platform_get_irq(pdev, 0);
	hs->irq = irq;

	r = request_threaded_irq(irq, NULL, retu_headset_hook_interrupt, 0,
			"hookdet", hs);
	if (r != 0) {
		dev_err(&pdev->dev, "hookdet IRQ not available\n");
		goto err6;
	}

	return 0;
err6:
	device_remove_file(&pdev->dev, &dev_attr_enable_det);
err5:
	device_remove_file(&pdev->dev, &dev_attr_enable);
err4:
	device_remove_file(&pdev->dev, &dev_attr_hookdet);
err3:
	input_unregister_device(hs->idev);
err2:
	input_free_device(hs->idev);
err1:
	kfree(hs);
	return r;
}
コード例 #11
0
ファイル: tca6416-keypad.c プロジェクト: ANFS/ANFS-kernel
static int __devinit tca6416_keypad_probe(struct i2c_client *client,
				   const struct i2c_device_id *id)
{
	struct tca6416_keys_platform_data *pdata;
	struct tca6416_keypad_chip *chip;
	struct input_dev *input;
	int error;
	int i;

	/* Check functionality */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
		dev_err(&client->dev, "%s adapter not supported\n",
			dev_driver_string(&client->adapter->dev));
		return -ENODEV;
	}

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_dbg(&client->dev, "no platform data\n");
		return -EINVAL;
	}

	chip = kzalloc(sizeof(struct tca6416_keypad_chip) +
		       pdata->nbuttons * sizeof(struct tca6416_button),
		       GFP_KERNEL);
	input = input_allocate_device();
	if (!chip || !input) {
		error = -ENOMEM;
		goto fail1;
	}

	chip->client = client;
	chip->input = input;
	chip->io_size = id->driver_data;
	chip->pinmask = pdata->pinmask;
	chip->use_polling = pdata->use_polling;

	INIT_DELAYED_WORK(&chip->dwork, tca6416_keys_work_func);

	input->phys = "tca6416-keys/input0";
	input->name = client->name;
	input->dev.parent = &client->dev;

	input->open = tca6416_keys_open;
	input->close = tca6416_keys_close;

	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0100;

	/* Enable auto repeat feature of Linux input subsystem */
	if (pdata->rep)
		__set_bit(EV_REP, input->evbit);

	for (i = 0; i < pdata->nbuttons; i++) {
		unsigned int type;

		chip->buttons[i] = pdata->buttons[i];
		type = (pdata->buttons[i].type) ?: EV_KEY;
		input_set_capability(input, type, pdata->buttons[i].code);
	}

	input_set_drvdata(input, chip);

	/*
	 * Initialize cached registers from their original values.
	 * we can't share this chip with another i2c master.
	 */
	error = tca6416_setup_registers(chip);
	if (error)
		goto fail1;

	if (!chip->use_polling) {
		if (pdata->irq_is_gpio)
			chip->irqnum = gpio_to_irq(client->irq);
		else
			chip->irqnum = client->irq;

		error = request_threaded_irq(chip->irqnum, NULL,
					     tca6416_keys_isr,
					     IRQF_TRIGGER_FALLING,
					     "tca6416-keypad", chip);
		if (error) {
			dev_dbg(&client->dev,
				"Unable to claim irq %d; error %d\n",
				chip->irqnum, error);
			goto fail1;
		}
		disable_irq(chip->irqnum);
	}

	error = input_register_device(input);
	if (error) {
		dev_dbg(&client->dev,
			"Unable to register input device, error: %d\n", error);
		goto fail2;
	}

	i2c_set_clientdata(client, chip);

	return 0;

fail2:
	if (!chip->use_polling) {
		free_irq(chip->irqnum, chip);
		enable_irq(chip->irqnum);
	}
fail1:
	input_free_device(input);
	kfree(chip);
	return error;
}
コード例 #12
0
static int hall_device_probe(struct i2c_client *client,
                  const struct i2c_device_id *id)
{
    int ret = 0;
	static struct hall_device_chip *chip;

    SENSOR_LOG_INFO("prob start\n");

    chip = kzalloc(sizeof(struct hall_device_chip), GFP_KERNEL);
    if (!chip) {
        ret = -ENOMEM;
        goto malloc_failed;
    }

	chip->client = client;
	i2c_set_clientdata(client, chip);

    hall_device_chip_data_init(chip);

    hall_device_parse_dt(chip);

    INIT_DELAYED_WORK(&chip->flush_work, hall_device_flush_work_func);

    SENSOR_LOG_INFO("hall_device_int_s is %d",chip->irq_s.irq_pin);
    SENSOR_LOG_INFO("hall_device_int_n is %d",chip->irq_n.irq_pin);

	mutex_init(&chip->lock);


    hall_device_class   = class_create(THIS_MODULE, "hall_device");

    chip->hall_device_dev = device_create(hall_device_class, NULL, hall_device_dev_t, &hall_device_driver ,"hall_device");
    if (IS_ERR(chip->hall_device_dev)) 
    {
       ret = PTR_ERR(chip->hall_device_dev);
       goto create_hall_device_dev_failed;
    }

	dev_set_drvdata(chip->hall_device_dev, chip);


    ret = gpio_request(chip->irq_s.irq_pin, "hall_device_irq_s");
    if (ret)    
    {
        SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_s.irq_pin);
        
        gpio_free(chip->irq_s.irq_pin);
        ret = gpio_request(chip->irq_s.irq_pin, "hall_device_irq_s");
        if (ret) 
        {
            SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_s.irq_pin);
            return ret;
        }
    }

    gpio_direction_input(chip->irq_s.irq_pin);
    gpio_set_value(chip->irq_s.irq_pin, 1);

    chip->irq_s.irq_num = gpio_to_irq(chip->irq_s.irq_pin);
    INIT_WORK(&chip->irq_work_s, hall_device_irq_work_s);
    ret = request_threaded_irq(chip->irq_s.irq_num, NULL, &hall_device_irq_s, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "hall_device_irq_s", chip);
    if (ret) {
        SENSOR_LOG_ERROR("Failed to request irq %d\n", chip->irq_s.irq_num);
        goto irq_s_register_fail;
    }


    ret = gpio_request(chip->irq_n.irq_pin, "hall_device_irq_n");
    if (ret)    
    {
        SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_n.irq_pin);
        
        gpio_free(chip->irq_n.irq_pin);
        ret = gpio_request(chip->irq_n.irq_pin, "hall_device_irq_n");
        if (ret) 
        {
            SENSOR_LOG_INFO("gpio %d is busy and then to free it\n",chip->irq_n.irq_pin);
            return ret;
        }
    }
    
    gpio_direction_input(chip->irq_n.irq_pin);
    gpio_set_value(chip->irq_n.irq_pin, 1);

    chip->irq_n.irq_num = gpio_to_irq(chip->irq_n.irq_pin);
    INIT_WORK(&chip->irq_work_n, hall_device_irq_work_n);
    ret = request_threaded_irq(chip->irq_n.irq_num , NULL, &hall_device_irq_n, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "hall_device_irq_n", chip);
    if (ret) {
        SENSOR_LOG_ERROR("Failed to request irq %d\n", chip->irq_n.irq_num );
        goto irq_n_register_fail;
    }

    chip->idev = input_allocate_device();
    if (!chip->idev) 
    {
        SENSOR_LOG_ERROR("no memory for idev\n");
        ret = -ENODEV;
        goto input_alloc_failed;
    }
    chip->idev->name = "hall_device";
    chip->idev->id.bustype = BUS_I2C;

    set_bit(EV_REL,     chip->idev->evbit);
    set_bit(REL_RX,     chip->idev->relbit);  //HALL S
    set_bit(REL_RY,     chip->idev->relbit);  //HALL N


    ret = input_register_device(chip->idev);
    if (ret) {
        input_free_device(chip->idev);
        SENSOR_LOG_ERROR("cant register input '%s'\n",chip->idev->name);
        goto input_register_failed;
    }

    create_sysfs_interfaces(chip->hall_device_dev);

    hall_device_irq_enable(&(chip->irq_s), false, true);
    hall_device_irq_enable(&(chip->irq_n), false, true);

    wake_lock_init(&chip->wakeup_wakelock.lock, WAKE_LOCK_SUSPEND, chip->wakeup_wakelock.name);
    hrtimer_init(&chip->unlock_wakelock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    chip->unlock_wakelock_timer.function = hall_device_unlock_wakelock_work_func;


    SENSOR_LOG_INFO("prob success\n");

    return 0;

input_register_failed:
    input_free_device(chip->idev);
input_alloc_failed:
malloc_failed:
irq_n_register_fail:
irq_s_register_fail:
create_hall_device_dev_failed:
    chip->hall_device_dev = NULL;
    class_destroy(hall_device_class);
    SENSOR_LOG_INFO("prob failed\n");

    return -1;

}
コード例 #13
0
static int __devinit sec_fuelgauge_probe(struct i2c_client *client,
						const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct sec_fuelgauge_info *fuelgauge;
	sec_battery_platform_data_t *pdata = NULL;
	struct battery_data_t *battery_data = NULL;
	int ret = 0;
	union power_supply_propval raw_soc_val;

	dev_info(&client->dev,
		"%s: SEC Fuelgauge Driver Loading\n", __func__);

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

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

	mutex_init(&fuelgauge->fg_lock);

	fuelgauge->client = client;
	
	if (client->dev.of_node) {
		int error;
		pdata = devm_kzalloc(&client->dev,
			sizeof(sec_battery_platform_data_t),
				GFP_KERNEL);
		if (!pdata) {
			dev_err(&client->dev, "Failed to allocate memory\n");
			ret = -ENOMEM;
			goto err_free;
		}
		battery_data = devm_kzalloc(&client->dev,
			sizeof(struct battery_data_t),
				GFP_KERNEL);
		if (!battery_data) {
			dev_err(&client->dev, "Failed to allocate memory\n");
			devm_kfree(&client->dev, pdata);
			ret = -ENOMEM;
			goto err_free;
		}
		pdata->battery_data = (void *)battery_data;
		fuelgauge->pdata = pdata;
		error = fuelgauge_parse_dt(&client->dev, fuelgauge);
		if (error) {
			dev_err(&client->dev,
				"%s: Failed to get fuel_int\n", __func__);
		}
	} else	{
		dev_err(&client->dev,
			"%s: Failed to get of_node\n", __func__);
		fuelgauge->pdata = client->dev.platform_data;
	}

	i2c_set_clientdata(client, fuelgauge);

	if (!sec_hal_fg_init(fuelgauge->client)) {
		dev_err(&client->dev,
			"%s: Failed to Initialize Fuelgauge\n", __func__);
		goto err_free;
	}

	fuelgauge->psy_fg.name		= "sec-fuelgauge";
	fuelgauge->psy_fg.type		= POWER_SUPPLY_TYPE_UNKNOWN;
	fuelgauge->psy_fg.get_property	= sec_fg_get_property;
	fuelgauge->psy_fg.set_property	= sec_fg_set_property;
	fuelgauge->psy_fg.properties	= sec_fuelgauge_props;
	fuelgauge->psy_fg.num_properties =
		ARRAY_SIZE(sec_fuelgauge_props);
	fuelgauge->capacity_max = fuelgauge->pdata->capacity_max;
	raw_soc_val.intval = SEC_FUELGAUGE_CAPACITY_TYPE_RAW;
	sec_hal_fg_get_property(fuelgauge->client,
			POWER_SUPPLY_PROP_CAPACITY, &raw_soc_val);
	raw_soc_val.intval /= 10;
	if(raw_soc_val.intval > fuelgauge->pdata->capacity_max)
		sec_fg_calculate_dynamic_scale(fuelgauge);
/*
	if (!fuelgauge->pdata->fg_gpio_init()) {
		dev_err(&client->dev,
			"%s: Failed to Initialize GPIO\n", __func__);
		goto err_free;
	}
*/
	ret = power_supply_register(&client->dev, &fuelgauge->psy_fg);
	if (ret) {
		dev_err(&client->dev,
			"%s: Failed to Register psy_fg\n", __func__);
		goto err_free;
	}

	if (fuelgauge->pdata->fg_irq) {
		fuelgauge->fg_irq = gpio_to_irq(fuelgauge->pdata->fg_irq);
		INIT_DELAYED_WORK(
			&fuelgauge->isr_work, sec_fg_isr_work);

		ret = request_threaded_irq(fuelgauge->fg_irq,
				NULL, sec_fg_irq_thread,
			        IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
				"fuelgauge-irq", fuelgauge);
		if (ret) {
			dev_err(&client->dev,
				"%s: Failed to Reqeust IRQ\n", __func__);
			goto err_supply_unreg;
		}

		ret = enable_irq_wake(fuelgauge->fg_irq);
		if (ret < 0)
			dev_err(&client->dev,
				"%s: Failed to Enable Wakeup Source(%d)\n",
				__func__, ret);
	}

	fuelgauge->is_fuel_alerted = false;
	if (fuelgauge->pdata->fuel_alert_soc >= 0) {
		if (sec_hal_fg_fuelalert_init(fuelgauge->client,
			fuelgauge->pdata->fuel_alert_soc))
			wake_lock_init(&fuelgauge->fuel_alert_wake_lock,
				WAKE_LOCK_SUSPEND, "fuel_alerted");
		else {
			dev_err(&client->dev,
				"%s: Failed to Initialize Fuel-alert\n",
				__func__);
			goto err_irq;
		}
	}

	fuelgauge->initial_update_of_soc = true;

	ret = sec_fg_create_attrs(fuelgauge->psy_fg.dev);
	if (ret) {
		dev_err(&client->dev,
			"%s : Failed to create_attrs\n", __func__);
		goto err_irq;
	}

	dev_info(&client->dev,
		"%s: SEC Fuelgauge Driver Loaded\n", __func__);
	return 0;

err_irq:
	if (fuelgauge->fg_irq)
		free_irq(fuelgauge->fg_irq, fuelgauge);
	wake_lock_destroy(&fuelgauge->fuel_alert_wake_lock);
err_supply_unreg:
	power_supply_unregister(&fuelgauge->psy_fg);
err_free:
	mutex_destroy(&fuelgauge->fg_lock);
	kfree(fuelgauge);

	return ret;
}
コード例 #14
0
static int __devinit ehci_hsic_msm_probe(struct platform_device *pdev)
{
	struct usb_hcd *hcd;
	struct resource *res;
	struct msm_hsic_hcd *mehci;
	struct msm_hsic_host_platform_data *pdata;
	int ret;

	dev_dbg(&pdev->dev, "ehci_msm-hsic probe\n");

	/* After parent device's probe is executed, it will be put in suspend
	 * mode. When child device's probe is called, driver core is not
	 * resuming parent device due to which parent will be in suspend even
	 * though child is active. Hence resume the parent device explicitly.
	 */
	if (pdev->dev.parent)
		pm_runtime_get_sync(pdev->dev.parent);

	hcd = usb_create_hcd(&msm_hsic_driver, &pdev->dev,
				dev_name(&pdev->dev));
	if (!hcd) {
		dev_err(&pdev->dev, "Unable to create HCD\n");
		return  -ENOMEM;
	}

	hcd->irq = platform_get_irq(pdev, 0);
	if (hcd->irq < 0) {
		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
		ret = hcd->irq;
		goto put_hcd;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "Unable to get memory resource\n");
		ret = -ENODEV;
		goto put_hcd;
	}

	hcd->rsrc_start = res->start;
	hcd->rsrc_len = resource_size(res);
	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
	if (!hcd->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto put_hcd;
	}

	mehci = hcd_to_hsic(hcd);
	mehci->dev = &pdev->dev;
	pdata = mehci->dev->platform_data;

	mehci->ehci.susp_sof_bug = 1;
	mehci->ehci.reset_sof_bug = 1;

	mehci->ehci.resume_sof_bug = 1;

	if (pdata)
		mehci->ehci.log2_irq_thresh = pdata->log2_irq_thresh;

	res = platform_get_resource_byname(pdev,
			IORESOURCE_IRQ,
			"peripheral_status_irq");
	if (res)
		mehci->peripheral_status_irq = res->start;

	res = platform_get_resource_byname(pdev, IORESOURCE_IO, "wakeup");
	if (res) {
		mehci->wakeup_gpio = res->start;
		mehci->wakeup_irq = MSM_GPIO_TO_INT(res->start);
		dev_dbg(mehci->dev, "wakeup_irq: %d\n", mehci->wakeup_irq);
	}

	ret = msm_hsic_init_clocks(mehci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize clocks\n");
		ret = -ENODEV;
		goto unmap;
	}

	ret = msm_hsic_init_vddcx(mehci, 1);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize VDDCX\n");
		ret = -ENODEV;
		goto deinit_clocks;
	}

	init_completion(&mehci->rt_completion);
	init_completion(&mehci->gpt0_completion);
	ret = msm_hsic_reset(mehci);
	if (ret) {
		dev_err(&pdev->dev, "unable to initialize PHY\n");
		goto deinit_vddcx;
	}

	ehci_wq = create_singlethread_workqueue("ehci_wq");
	if (!ehci_wq) {
		dev_err(&pdev->dev, "unable to create workqueue\n");
		ret = -ENOMEM;
		goto deinit_vddcx;
	}

	INIT_WORK(&mehci->bus_vote_w, ehci_hsic_bus_vote_w);

	ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED);
	if (ret) {
		dev_err(&pdev->dev, "unable to register HCD\n");
		goto unconfig_gpio;
	}

	device_init_wakeup(&pdev->dev, 1);
	wake_lock_init(&mehci->wlock, WAKE_LOCK_SUSPEND, dev_name(&pdev->dev));
	wake_lock(&mehci->wlock);

	if (mehci->peripheral_status_irq) {
		ret = request_threaded_irq(mehci->peripheral_status_irq,
			NULL, hsic_peripheral_status_change,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
						| IRQF_SHARED,
			"hsic_peripheral_status", mehci);
		if (ret)
			dev_err(&pdev->dev, "%s:request_irq:%d failed:%d",
				__func__, mehci->peripheral_status_irq, ret);
	}

	/* configure wakeup irq */
	if (mehci->wakeup_irq) {
		ret = request_irq(mehci->wakeup_irq, msm_hsic_wakeup_irq,
				IRQF_TRIGGER_HIGH,
				"msm_hsic_wakeup", mehci);
		if (!ret) {
			disable_irq_nosync(mehci->wakeup_irq);
		} else {
			dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
					mehci->wakeup_irq, ret);
			mehci->wakeup_irq = 0;
		}
	}

	ret = ehci_hsic_msm_debugfs_init(mehci);
	if (ret)
		dev_dbg(&pdev->dev, "mode debugfs file is"
			"not available\n");

	if (pdata && pdata->bus_scale_table) {
		mehci->bus_perf_client =
		    msm_bus_scale_register_client(pdata->bus_scale_table);
		/* Configure BUS performance parameters for MAX bandwidth */
		if (mehci->bus_perf_client) {
			mehci->bus_vote = true;
			queue_work(ehci_wq, &mehci->bus_vote_w);
		} else {
			dev_err(&pdev->dev, "%s: Failed to register BUS "
						"scaling client!!\n", __func__);
		}
	}

	__mehci = mehci;

	/*
	 * This pdev->dev is assigned parent of root-hub by USB core,
	 * hence, runtime framework automatically calls this driver's
	 * runtime APIs based on root-hub's state.
	 */
	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);
	/* Decrement the parent device's counter after probe.
	 * As child is active, parent will not be put into
	 * suspend mode.
	 */
	if (pdev->dev.parent)
		pm_runtime_put_sync(pdev->dev.parent);

	return 0;

unconfig_gpio:
	destroy_workqueue(ehci_wq);
	msm_hsic_config_gpios(mehci, 0);
deinit_vddcx:
	msm_hsic_init_vddcx(mehci, 0);
deinit_clocks:
	msm_hsic_init_clocks(mehci, 0);
unmap:
	iounmap(hcd->regs);
put_hcd:
	usb_put_hcd(hcd);

	return ret;
}
コード例 #15
0
static int crystalcove_chgr_probe(struct platform_device *pdev)
{
	struct chgr_info *info;
	int ret;

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
	if (!info) {
		dev_err(&pdev->dev, "mem alloc failed\n");
		return -ENOMEM;
	}

	dev_info(&pdev->dev, "crystalcove charger probe begin\n");

	info->pdev = pdev;
#ifdef CONFIG_ACPI
	info->pdata = crystalcove_chgr_pdata(NULL);
#else
	info->pdata = pdev->dev.platform_data;
#endif

	platform_set_drvdata(pdev, info);

	mutex_init(&info->lock);
	INIT_WORK(&info->otg_work, crystalcove_otg_event_worker);

	info->irq = platform_get_irq(pdev, 0);

	ret = request_threaded_irq(info->irq, NULL, crystalcove_chgr_isr,
				IRQF_TRIGGER_RISING | IRQF_ONESHOT, CHGR_DRV_NAME, info);
	if (ret) {
		dev_err(&pdev->dev, "unable to register irq %d\n", info->irq);
		goto psy_reg_failed;
	}

	info->otg = usb_get_phy(USB_PHY_TYPE_USB2);

	if (!info->otg) {
		dev_warn(&pdev->dev, "Failed to get otg transceiver!!\n");
	} else {
		info->id_nb.notifier_call = crystalcove_handle_otg_event;
		ret = usb_register_notifier(info->otg, &info->id_nb);
		if (ret)
			dev_err(&pdev->dev, "failed to register otg notifier\n");
	}

	info->max_cc = info->pdata->max_cc;
	info->max_cv = info->pdata->max_cv;

	info->psy_usb.name = CHGR_DRV_NAME;
	info->psy_usb.type = POWER_SUPPLY_TYPE_USB;
	info->psy_usb.properties = crystalcove_chrg_usb_props;
	info->psy_usb.num_properties = ARRAY_SIZE(crystalcove_chrg_usb_props);
	info->psy_usb.get_property = crystalcove_chgr_usb_get_property;
	info->psy_usb.set_property = crystalcove_chgr_usb_set_property;
	info->psy_usb.supplied_to = info->pdata->supplied_to;
	info->psy_usb.num_supplicants = info->pdata->num_supplicants;
	info->psy_usb.throttle_states = info->pdata->throttle_states;
	info->psy_usb.num_throttle_states = info->pdata->num_throttle_states;
	info->psy_usb.supported_cables = info->pdata->supported_cables;

	ret = power_supply_register(&pdev->dev, &info->psy_usb);

	if (ret) {
		dev_err(&pdev->dev, "Failed: power supply register (%d)\n",
			ret);
		goto psy_reg_failed;
	}

	/* unmask the CHGR interrupts */
	intel_mid_pmic_writeb(CRYSTALCOVE_MCHGRIRQS0_REG, 0x00);
	intel_mid_pmic_writeb(CRYSTALCOVE_MCHGRIRQSX_REG, 0x00);
	return 0;
psy_reg_failed:
	return ret;
}
コード例 #16
0
static int headset_switch_probe(struct platform_device *pdev)
{
	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct pm860x_headset_info *info;
	struct pm860x_platform_data *pm860x_pdata;
	struct gpio_switch_platform_data *pdata_headset = pdev->dev.platform_data;
	struct gpio_switch_platform_data *pdata_hook = pdata_headset + 1;
	struct headset_switch_data *switch_data_headset, *switch_data_hook;
	int irq_headset, irq_hook, ret = 0;

	if (pdev->dev.parent->platform_data) {
		pm860x_pdata = pdev->dev.parent->platform_data;
	} else {
		pr_debug("Invalid pm860x platform data!\n");
		return -EINVAL;
	}

	if (pdata_headset == NULL || pdata_hook == NULL) {
		pr_debug("Invalid gpio switch platform data!\n");
		return -EBUSY;
	}

	irq_headset = platform_get_irq(pdev, 0);
	if (irq_headset < 0) {
		dev_err(&pdev->dev, "No IRQ resource for headset!\n");
		return -EINVAL;
	}
	irq_hook = platform_get_irq(pdev, 1);
	if (irq_hook < 0) {
		dev_err(&pdev->dev, "No IRQ resource for hook!\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(struct pm860x_headset_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;
	info->chip = chip;
	info->dev = &pdev->dev;
	info->irq_headset = irq_headset + chip->irq_base;
	info->irq_hook = irq_hook + chip->irq_base;
	info->headset_flag = pm860x_pdata->headset_flag;
	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;

	switch_data_headset = kzalloc(sizeof(struct headset_switch_data), GFP_KERNEL);
	if (!switch_data_headset)
		return -ENOMEM;
	switch_data_hook = kzalloc(sizeof(struct headset_switch_data), GFP_KERNEL);
	if (!switch_data_hook)
		return -ENOMEM;

	switch_data_headset->sdev.name = pdata_headset->name;
	switch_data_headset->name_on = pdata_headset->name_on;
	switch_data_headset->name_off = pdata_headset->name_off;
	switch_data_headset->state_on = pdata_headset->state_on;
	switch_data_headset->state_off = pdata_headset->state_off;
	switch_data_headset->sdev.print_state = switch_headset_print_state;
	info->psw_data_headset = switch_data_headset;

	switch_data_hook->sdev.name = pdata_hook->name;
	switch_data_hook->name_on = pdata_hook->name_on;
	switch_data_hook->name_off = pdata_hook->name_off;
	switch_data_hook->state_on = pdata_hook->state_on;
	switch_data_hook->state_off = pdata_hook->state_off;
	switch_data_hook->sdev.print_state = switch_headset_print_state;
	info->psw_data_hook = switch_data_hook;

	ret = switch_dev_register(&switch_data_headset->sdev);
	if (ret < 0)
		goto err_switch_dev_register;
	ret = switch_dev_register(&switch_data_hook->sdev);
	if (ret < 0)
		goto err_switch_dev_register;

	ret = request_threaded_irq(info->irq_headset, NULL, pm860x_headset_handler,
				   IRQF_ONESHOT, "headset", info);
	if (ret < 0) {
		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
			info->irq_headset, ret);
		goto out_irq_headset;
	}
	ret = request_threaded_irq(info->irq_hook, NULL, pm860x_headset_handler,
				   IRQF_ONESHOT, "hook", info);
	if (ret < 0) {
		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
			info->irq_hook, ret);
		goto out_irq_hook;
	}

	platform_set_drvdata(pdev, info);

	/* set hook detection debounce time to 24ms, it's the best setting we experienced */
	pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_BTN_DBNC, 0x10);

	//pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_PERIOD, 0x04);
	
	/* set headset period to continuous detection */
	pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_PERIOD, 0x06);

	/* set MIC detection parameter: MIC period set to 250msec */
	pm860x_reg_write(info->i2c, PM8607_MIC_DECTION, 0xDC);

	/* mask hook interrupt since we don't want the first false hook press down detection
	when inserting a headset without Mic */
	pm860x_set_bits(info->i2c, PM8607_INT_MASK_3, PM8607_INT_EN_HOOK, 0);

	/* enable headset detection */
	pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_EN_HS_DET, 1);

	INIT_WORK(&info->work_headset, headset_switch_work);
	INIT_WORK(&info->work_hook, hook_switch_work);

	/* Perform initial detection */
	headset_switch_work(&info->work_headset);
	hook_switch_work(&info->work_hook);

	return 0;

err_switch_dev_register:
	kfree(switch_data_headset);
	kfree(switch_data_hook);

out_irq_hook:
	free_irq(info->irq_headset, info);
out_irq_headset:
	kfree(info);
	return ret;
}
コード例 #17
0
static int sh_mmcif_probe(struct platform_device *pdev)
{
	int ret = 0, irq[2];
	struct mmc_host *mmc;
	struct sh_mmcif_host *host;
	struct sh_mmcif_plat_data *pd = pdev->dev.platform_data;
	struct resource *res;
	void __iomem *reg;

	irq[0] = platform_get_irq(pdev, 0);
	irq[1] = platform_get_irq(pdev, 1);
	if (irq[0] < 0 || irq[1] < 0) {
		dev_err(&pdev->dev, "Get irq error\n");
		return -ENXIO;
	}
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "platform_get_resource error.\n");
		return -ENXIO;
	}
	reg = ioremap(res->start, resource_size(res));
	if (!reg) {
		dev_err(&pdev->dev, "ioremap error.\n");
		return -ENOMEM;
	}

	mmc = mmc_alloc_host(sizeof(struct sh_mmcif_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto ealloch;
	}
	host		= mmc_priv(mmc);
	host->mmc	= mmc;
	host->addr	= reg;
	host->timeout	= 1000;

	host->pd = pdev;

	spin_lock_init(&host->lock);

	mmc->ops = &sh_mmcif_ops;
	sh_mmcif_init_ocr(host);

	mmc->caps = MMC_CAP_MMC_HIGHSPEED;
	if (pd && pd->caps)
		mmc->caps |= pd->caps;
	mmc->max_segs = 32;
	mmc->max_blk_size = 512;
	mmc->max_req_size = PAGE_CACHE_SIZE * mmc->max_segs;
	mmc->max_blk_count = mmc->max_req_size / mmc->max_blk_size;
	mmc->max_seg_size = mmc->max_req_size;

	platform_set_drvdata(pdev, host);

	pm_runtime_enable(&pdev->dev);
	host->power = false;

	host->hclk = clk_get(&pdev->dev, NULL);
	if (IS_ERR(host->hclk)) {
		ret = PTR_ERR(host->hclk);
		dev_err(&pdev->dev, "cannot get clock: %d\n", ret);
		goto eclkget;
	}
	ret = sh_mmcif_clk_update(host);
	if (ret < 0)
		goto eclkupdate;

	ret = pm_runtime_resume(&pdev->dev);
	if (ret < 0)
		goto eresume;

	INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);

	sh_mmcif_sync_reset(host);
	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);

	ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
	if (ret) {
		dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
		goto ereqirq0;
	}
	ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
	if (ret) {
		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
		goto ereqirq1;
	}

	if (pd && pd->use_cd_gpio) {
		ret = mmc_gpio_request_cd(mmc, pd->cd_gpio);
		if (ret < 0)
			goto erqcd;
	}

	clk_disable(host->hclk);
	ret = mmc_add_host(mmc);
	if (ret < 0)
		goto emmcaddh;

	dev_pm_qos_expose_latency_limit(&pdev->dev, 100);

	dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
	dev_dbg(&pdev->dev, "chip ver H'%04x\n",
		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
	return ret;

emmcaddh:
	if (pd && pd->use_cd_gpio)
		mmc_gpio_free_cd(mmc);
erqcd:
	free_irq(irq[1], host);
ereqirq1:
	free_irq(irq[0], host);
ereqirq0:
	pm_runtime_suspend(&pdev->dev);
eresume:
	clk_disable(host->hclk);
eclkupdate:
	clk_put(host->hclk);
eclkget:
	pm_runtime_disable(&pdev->dev);
	mmc_free_host(mmc);
ealloch:
	iounmap(reg);
	return ret;
}
コード例 #18
0
static int __devinit twl6030_usb_probe(struct platform_device *pdev)
{
	struct twl6030_usb	*twl;
	int			status, err;
	struct twl4030_usb_data *pdata;
	struct device *dev = &pdev->dev;
	pdata = dev->platform_data;

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

	twl->dev		= &pdev->dev;
	twl->irq1		= platform_get_irq(pdev, 0);
	twl->irq2		= platform_get_irq(pdev, 1);
	twl->features		= pdata->features;
	twl->otg.dev		= twl->dev;
	twl->otg.label		= "twl6030";
	twl->otg.set_host	= twl6030_set_host;
	twl->otg.set_peripheral	= twl6030_set_peripheral;
	twl->otg.set_vbus	= twl6030_set_vbus;
	twl->otg.init		= twl6030_phy_init;
	twl->otg.shutdown	= twl6030_phy_shutdown;
	twl->otg.set_suspend	= twl6030_phy_suspend;
	twl->otg.start_srp	= twl6030_start_srp;

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl6030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(twl);
		return err;
	}
	otg_set_transceiver(&twl->otg);

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	ATOMIC_INIT_NOTIFIER_HEAD(&twl->otg.notifier);

	INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);

	twl->vbus_enable = false;
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq1, status);
		device_remove_file(twl->dev, &dev_attr_vbus);
		kfree(twl);
		return status;
	}

	status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq2, status);
		free_irq(twl->irq1, twl);
		device_remove_file(twl->dev, &dev_attr_vbus);
		kfree(twl);
		return status;
	}

	twl->asleep = 0;
	pdata->phy_init(dev);
	twl6030_phy_suspend(&twl->otg, 0);
	twl6030_enable_irq(&twl->otg);
	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");

	return 0;
}
コード例 #19
0
int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res)
{
	int i, ret;
	u8 irq_level[wcd9xxx_res->num_irq_regs];

	mutex_init(&wcd9xxx_res->irq_lock);
	mutex_init(&wcd9xxx_res->nested_irq_lock);

	wcd9xxx_res->irq = wcd9xxx_irq_get_upstream_irq(wcd9xxx_res);
	if (!wcd9xxx_res->irq) {
		pr_warn("%s: irq driver is not yet initialized\n", __func__);
		mutex_destroy(&wcd9xxx_res->irq_lock);
		mutex_destroy(&wcd9xxx_res->nested_irq_lock);
		return -EPROBE_DEFER;
	}
	pr_debug("%s: probed irq %d\n", __func__, wcd9xxx_res->irq);

	/* Setup downstream IRQs */
	ret = wcd9xxx_irq_setup_downstream_irq(wcd9xxx_res);
	if (ret) {
		pr_err("%s: Failed to setup downstream IRQ\n", __func__);
		wcd9xxx_irq_put_upstream_irq(wcd9xxx_res);
		mutex_destroy(&wcd9xxx_res->irq_lock);
		mutex_destroy(&wcd9xxx_res->nested_irq_lock);
		return ret;
	}

	/* All other wcd9xxx interrupts are edge triggered */
	wcd9xxx_res->irq_level_high[0] = true;

	/* mask all the interrupts */
	memset(irq_level, 0, wcd9xxx_res->num_irq_regs);
	for (i = 0; i < wcd9xxx_res->num_irqs; i++) {
		wcd9xxx_res->irq_masks_cur[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
		wcd9xxx_res->irq_masks_cache[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
		irq_level[BIT_BYTE(i)] |=
		    wcd9xxx_res->irq_level_high[i] << (i % BITS_PER_BYTE);
	}

	if (!wcd9xxx_res->codec_reg_write) {
		dev_err(wcd9xxx_res->dev,
				"%s: Codec Register write callback not defined\n",
			   __func__);
		ret = -EINVAL;
		goto fail_irq_init;
	}

	for (i = 0; i < wcd9xxx_res->num_irq_regs; i++) {
		/* Initialize interrupt mask and level registers */
		wcd9xxx_res->codec_reg_write(wcd9xxx_res,
					WCD9XXX_A_INTR_LEVEL0 + i,
					irq_level[i]);
		wcd9xxx_res->codec_reg_write(wcd9xxx_res,
					WCD9XXX_A_INTR_MASK0 + i,
					wcd9xxx_res->irq_masks_cur[i]);
	}

	ret = request_threaded_irq(wcd9xxx_res->irq, NULL, wcd9xxx_irq_thread,
				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
				   "wcd9xxx", wcd9xxx_res);
	if (ret != 0)
		dev_err(wcd9xxx_res->dev, "Failed to request IRQ %d: %d\n",
			wcd9xxx_res->irq, ret);
	else {
		ret = enable_irq_wake(wcd9xxx_res->irq);
		if (ret)
			dev_err(wcd9xxx_res->dev,
				"Failed to set wake interrupt on IRQ %d: %d\n",
				wcd9xxx_res->irq, ret);
		if (ret)
			free_irq(wcd9xxx_res->irq, wcd9xxx_res);
	}

	if (ret)
		goto fail_irq_init;

	return ret;

fail_irq_init:
	dev_err(wcd9xxx_res->dev,
			"%s: Failed to init wcd9xxx irq\n", __func__);
	wcd9xxx_irq_put_upstream_irq(wcd9xxx_res);
	mutex_destroy(&wcd9xxx_res->irq_lock);
	mutex_destroy(&wcd9xxx_res->nested_irq_lock);
	return ret;
}
コード例 #20
0
static int mhl_i2c_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int rc = 0;
	struct mhl_tx_platform_data *pdata = NULL;
	struct mhl_tx_ctrl *mhl_ctrl;
	struct usb_ext_notification *mhl_info = NULL;

	mhl_ctrl = devm_kzalloc(&client->dev, sizeof(*mhl_ctrl), GFP_KERNEL);
	if (!mhl_ctrl) {
		pr_err("%s: FAILED: cannot alloc hdmi tx ctrl\n", __func__);
		rc = -ENOMEM;
		goto failed_no_mem;
	}

	if (client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
			     sizeof(struct mhl_tx_platform_data), GFP_KERNEL);
		if (!pdata) {
			dev_err(&client->dev, "Failed to allocate memory\n");
			rc = -ENOMEM;
			goto failed_no_mem;
		}

		rc = mhl_tx_get_dt_data(&client->dev, pdata);
		if (rc) {
			pr_err("%s: FAILED: parsing device tree data; rc=%d\n",
				__func__, rc);
			goto failed_dt_data;
		}
		mhl_ctrl->i2c_handle = client;
		mhl_ctrl->pdata = pdata;
		i2c_set_clientdata(client, mhl_ctrl);
	}

	/*
	 * Regulator init
	 */
	rc = mhl_vreg_config(mhl_ctrl, 1);
	if (rc) {
		pr_err("%s: vreg init failed [%d]\n",
			__func__, rc);
		goto failed_probe;
	}

	/*
	 * GPIO init
	 */
	rc = mhl_gpio_config(mhl_ctrl, 1);
	if (rc) {
		pr_err("%s: gpio init failed [%d]\n",
			__func__, rc);
		goto failed_probe;
	}

	/*
	 * Other initializations
	 * such tx specific
	 */
	mhl_ctrl->disc_enabled = false;
	rc = mhl_tx_chip_init(mhl_ctrl);
	if (rc) {
		pr_err("%s: tx chip init failed [%d]\n",
			__func__, rc);
		goto failed_probe;
	}

	init_completion(&mhl_ctrl->rgnd_done);

	pr_debug("%s: IRQ from GPIO INTR = %d\n",
		__func__, mhl_ctrl->i2c_handle->irq);
	pr_debug("%s: Driver name = [%s]\n", __func__,
		client->dev.driver->name);
	rc = request_threaded_irq(mhl_ctrl->i2c_handle->irq, NULL,
				   &mhl_tx_isr,
				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				 client->dev.driver->name, mhl_ctrl);
	if (rc) {
		pr_err("request_threaded_irq failed, status: %d\n",
			rc);
		goto failed_probe;
	} else {
		pr_debug("request_threaded_irq succeeded\n");
	}

	mhl_ctrl->mhl_psy.name = "ext-vbus";
	mhl_ctrl->mhl_psy.type = POWER_SUPPLY_TYPE_USB_DCP;
	mhl_ctrl->mhl_psy.supplied_to = mhl_pm_power_supplied_to;
	mhl_ctrl->mhl_psy.num_supplicants = ARRAY_SIZE(
					mhl_pm_power_supplied_to);
	mhl_ctrl->mhl_psy.properties = mhl_pm_power_props;
	mhl_ctrl->mhl_psy.num_properties = ARRAY_SIZE(mhl_pm_power_props);
	mhl_ctrl->mhl_psy.get_property = mhl_power_get_property;
	mhl_ctrl->mhl_psy.set_property = mhl_power_set_property;

	rc = power_supply_register(&client->dev, &mhl_ctrl->mhl_psy);
	if (rc < 0) {
		dev_err(&client->dev, "%s:power_supply_register ext_vbus_psy failed\n",
			__func__);
		goto failed_probe;
	}

	pr_debug("%s: i2c client addr is [%x]\n", __func__, client->addr);

	mhl_info = devm_kzalloc(&client->dev, sizeof(*mhl_info), GFP_KERNEL);
	if (!mhl_info) {
		pr_err("%s: alloc mhl info failed\n", __func__);
		goto failed_probe;
	}

	mhl_info->ctxt = mhl_ctrl;
	mhl_info->notify = mhl_sii_device_discovery;
	if (msm_register_usb_ext_notification(mhl_info)) {
		pr_err("%s: register for usb notifcn failed\n", __func__);
		goto failed_probe;
	}
	mhl_ctrl->mhl_info = mhl_info;
	return 0;
failed_probe:
	mhl_gpio_config(mhl_ctrl, 0);
	mhl_vreg_config(mhl_ctrl, 0);
	/* do not deep-free */
	if (mhl_info)
		devm_kfree(&client->dev, mhl_info);
failed_dt_data:
	if (pdata)
		devm_kfree(&client->dev, pdata);
failed_no_mem:
	if (mhl_ctrl)
		devm_kfree(&client->dev, mhl_ctrl);
	pr_err("%s: PROBE FAILED, rc=%d\n", __func__, rc);
	return rc;
}
コード例 #21
0
struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq,
			    const struct ad7879_bus_ops *bops)
{
	struct ad7879_platform_data *pdata = dev->platform_data;
	struct ad7879 *ts;
	struct input_dev *input_dev;
	int err;
	u16 revid;

	if (!irq) {
		dev_err(dev, "no IRQ?\n");
		err = -EINVAL;
		goto err_out;
	}

	if (!pdata) {
		dev_err(dev, "no platform data?\n");
		err = -EINVAL;
		goto err_out;
	}

	ts = kzalloc(sizeof(*ts), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!ts || !input_dev) {
		err = -ENOMEM;
		goto err_free_mem;
	}

	ts->bops = bops;
	ts->dev = dev;
	ts->input = input_dev;
	ts->irq = irq;

	setup_timer(&ts->timer, ad7879_timer, (unsigned long) ts);

	ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
	ts->pressure_max = pdata->pressure_max ? : ~0;

	ts->first_conversion_delay = pdata->first_conversion_delay;
	ts->acquisition_time = pdata->acquisition_time;
	ts->averaging = pdata->averaging;
	ts->pen_down_acc_interval = pdata->pen_down_acc_interval;
	ts->median = pdata->median;

	snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));

	input_dev->name = "AD7879 Touchscreen";
	input_dev->phys = ts->phys;
	input_dev->dev.parent = dev;
	input_dev->id.bustype = bops->bustype;

	input_dev->open = ad7879_open;
	input_dev->close = ad7879_close;

	input_set_drvdata(input_dev, ts);

	__set_bit(EV_ABS, input_dev->evbit);
	__set_bit(ABS_X, input_dev->absbit);
	__set_bit(ABS_Y, input_dev->absbit);
	__set_bit(ABS_PRESSURE, input_dev->absbit);

	__set_bit(EV_KEY, input_dev->evbit);
	__set_bit(BTN_TOUCH, input_dev->keybit);

	input_set_abs_params(input_dev, ABS_X,
			pdata->x_min ? : 0,
			pdata->x_max ? : MAX_12BIT,
			0, 0);
	input_set_abs_params(input_dev, ABS_Y,
			pdata->y_min ? : 0,
			pdata->y_max ? : MAX_12BIT,
			0, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE,
			pdata->pressure_min, pdata->pressure_max, 0, 0);

	err = ad7879_write(ts, AD7879_REG_CTRL2, AD7879_RESET);
	if (err < 0) {
		dev_err(dev, "Failed to write %s\n", input_dev->name);
		goto err_free_mem;
	}

	revid = ad7879_read(ts, AD7879_REG_REVID);
	input_dev->id.product = (revid & 0xff);
	input_dev->id.version = revid >> 8;
	if (input_dev->id.product != devid) {
		dev_err(dev, "Failed to probe %s (%x vs %x)\n",
			input_dev->name, devid, revid);
		err = -ENODEV;
		goto err_free_mem;
	}

	ts->cmd_crtl3 = AD7879_YPLUS_BIT |
			AD7879_XPLUS_BIT |
			AD7879_Z2_BIT |
			AD7879_Z1_BIT |
			AD7879_TEMPMASK_BIT |
			AD7879_AUXVBATMASK_BIT |
			AD7879_GPIOALERTMASK_BIT;

	ts->cmd_crtl2 = AD7879_PM(AD7879_PM_DYN) | AD7879_DFR |
			AD7879_AVG(ts->averaging) |
			AD7879_MFS(ts->median) |
			AD7879_FCD(ts->first_conversion_delay);

	ts->cmd_crtl1 = AD7879_MODE_INT | AD7879_MODE_SEQ1 |
			AD7879_ACQ(ts->acquisition_time) |
			AD7879_TMR(ts->pen_down_acc_interval);

	err = request_threaded_irq(ts->irq, NULL, ad7879_irq,
				   IRQF_TRIGGER_FALLING,
				   dev_name(dev), ts);
	if (err) {
		dev_err(dev, "irq %d busy?\n", ts->irq);
		goto err_free_mem;
	}

	__ad7879_disable(ts);

	err = sysfs_create_group(&dev->kobj, &ad7879_attr_group);
	if (err)
		goto err_free_irq;

	err = ad7879_gpio_add(ts, pdata);
	if (err)
		goto err_remove_attr;

	err = input_register_device(input_dev);
	if (err)
		goto err_remove_gpio;

	return ts;

err_remove_gpio:
	ad7879_gpio_remove(ts);
err_remove_attr:
	sysfs_remove_group(&dev->kobj, &ad7879_attr_group);
err_free_irq:
	free_irq(ts->irq, ts);
err_free_mem:
	input_free_device(input_dev);
	kfree(ts);
err_out:
	return ERR_PTR(err);
}
コード例 #22
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;

    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);

    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");


    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;
    }

    ret = create_sysfs_interfaces(&client->dev);
    if (ret < 0) {
        pr_err("%s : sysfs register failed", __func__);
        goto err3;
    }

    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;
}
コード例 #23
0
ファイル: as5011.c プロジェクト: AllenWeb/linux
static int __devinit as5011_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	const struct as5011_platform_data *plat_data;
	struct as5011_device *as5011;
	struct input_dev *input_dev;
	int irq;
	int error;

	plat_data = client->dev.platform_data;
	if (!plat_data)
		return -EINVAL;

	if (!plat_data->axis_irq) {
		dev_err(&client->dev, "No axis IRQ?\n");
		return -EINVAL;
	}

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_NOSTART |
				     I2C_FUNC_PROTOCOL_MANGLING)) {
		dev_err(&client->dev,
			"need i2c bus that supports protocol mangling\n");
		return -ENODEV;
	}

	as5011 = kmalloc(sizeof(struct as5011_device), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!as5011 || !input_dev) {
		dev_err(&client->dev,
			"Can't allocate memory for device structure\n");
		error = -ENOMEM;
		goto err_free_mem;
	}

	as5011->i2c_client = client;
	as5011->input_dev = input_dev;
	as5011->button_gpio = plat_data->button_gpio;
	as5011->axis_irq = plat_data->axis_irq;

	input_dev->name = "Austria Microsystem as5011 joystick";
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;

	__set_bit(EV_KEY, input_dev->evbit);
	__set_bit(EV_ABS, input_dev->evbit);
	__set_bit(BTN_JOYSTICK, input_dev->keybit);

	input_set_abs_params(input_dev, ABS_X,
		AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
	input_set_abs_params(as5011->input_dev, ABS_Y,
		AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);

	error = gpio_request(as5011->button_gpio, "AS5011 button");
	if (error < 0) {
		dev_err(&client->dev, "Failed to request button gpio\n");
		goto err_free_mem;
	}

	irq = gpio_to_irq(as5011->button_gpio);
	if (irq < 0) {
		dev_err(&client->dev,
			"Failed to get irq number for button gpio\n");
		goto err_free_button_gpio;
	}

	as5011->button_irq = irq;

	error = request_threaded_irq(as5011->button_irq,
				     NULL, as5011_button_interrupt,
				     IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				     "as5011_button", as5011);
	if (error < 0) {
		dev_err(&client->dev,
			"Can't allocate button irq %d\n", as5011->button_irq);
		goto err_free_button_gpio;
	}

	error = as5011_configure_chip(as5011, plat_data);
	if (error)
		goto err_free_button_irq;

	error = request_threaded_irq(as5011->axis_irq, NULL,
				     as5011_axis_interrupt,
				     plat_data->axis_irqflags,
				     "as5011_joystick", as5011);
	if (error) {
		dev_err(&client->dev,
			"Can't allocate axis irq %d\n", plat_data->axis_irq);
		goto err_free_button_irq;
	}

	error = input_register_device(as5011->input_dev);
	if (error) {
		dev_err(&client->dev, "Failed to register input device\n");
		goto err_free_axis_irq;
	}

	i2c_set_clientdata(client, as5011);

	return 0;

err_free_axis_irq:
	free_irq(as5011->axis_irq, as5011);
err_free_button_irq:
	free_irq(as5011->button_irq, as5011);
err_free_button_gpio:
	gpio_free(as5011->button_gpio);
err_free_mem:
	input_free_device(input_dev);
	kfree(as5011);

	return error;
}
コード例 #24
0
static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client,
						  const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct max17047_fuelgauge_data *fg_data;
	struct max17047_platform_data *pdata = client->dev.platform_data;
	int ret = -ENODEV;
	int rawsoc, firstsoc;
	pr_info("%s: fuelgauge init\n", __func__);

	if (!pdata) {
		pr_err("%s: no platform data\n", __func__);
		return -ENODEV;
	}

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

	fg_data = kzalloc(sizeof(struct max17047_fuelgauge_data), GFP_KERNEL);
	if (!fg_data)
		return -ENOMEM;

	fg_data->client = client;
	fg_data->pdata = pdata;

	i2c_set_clientdata(client, fg_data);

	mutex_init(&fg_data->irq_lock);

	wake_lock_init(&fg_data->update_wake_lock, WAKE_LOCK_SUSPEND,
							       "fuel-update");

#ifdef USE_TRIM_ERROR_DETECTION
	/* trim error detect */
	fg_data->trim_err = max17047_detect_trim_error(fg_data);
#endif

	/* Initialize full_soc, set this before fisrt SOC reading */
	fg_data->full_soc = FULL_SOC_DEFAULT;
	/* first full_soc update */
	rawsoc = max17047_get_rawsoc(fg_data->client);
	if (rawsoc > FULL_SOC_DEFAULT)
		max17047_adjust_fullsoc(client);
	firstsoc = max17047_get_soc(client);
	pr_info("%s: rsoc=%d, fsoc=%d, soc=%d\n", __func__,
			rawsoc, fg_data->full_soc, firstsoc);

	if (fg_data->pdata->psy_name)
		fg_data->fuelgauge.name =
			fg_data->pdata->psy_name;
	else
		fg_data->fuelgauge.name = "max17047-fuelgauge";

#if defined(CONFIG_MACH_GC1)
	fg_data->prev_status = POWER_SUPPLY_STATUS_DISCHARGING;
#endif
	fg_data->fuelgauge.type = POWER_SUPPLY_TYPE_BATTERY;
	fg_data->fuelgauge.properties = max17047_fuelgauge_props;
	fg_data->fuelgauge.num_properties =
				ARRAY_SIZE(max17047_fuelgauge_props);
	fg_data->fuelgauge.get_property = max17047_get_property;
	fg_data->fuelgauge.set_property = max17047_set_property;

	ret = power_supply_register(&client->dev, &fg_data->fuelgauge);
	if (ret) {
		pr_err("%s: failed power supply register\n", __func__);
		goto err_psy_reg_fg;
	}

	/* Initialize fuelgauge registers */
	max17047_reg_init(fg_data);

	/* Initialize fuelgauge alert */
	max17047_alert_init(fg_data);

	INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work,
					max17047_update_work);

	/* Request IRQ */
	fg_data->irq = gpio_to_irq(fg_data->pdata->irq_gpio);
	ret = gpio_request(fg_data->pdata->irq_gpio, "fuelgauge-irq");
	if (ret) {
		pr_err("%s: failed requesting gpio %d\n", __func__,
				fg_data->pdata->irq_gpio);
		goto err_irq;
	}
	gpio_direction_input(fg_data->pdata->irq_gpio);
	gpio_free(fg_data->pdata->irq_gpio);

	ret = request_threaded_irq(fg_data->irq, NULL,
				max17047_fuelgauge_isr, IRQF_TRIGGER_FALLING,
				"max17047-alert", fg_data);
	if (ret < 0) {
		pr_err("%s: fail to request max17047 irq: %d: %d\n",
				__func__, fg_data->irq, ret);
		goto err_irq;
	}

	ret = enable_irq_wake(fg_data->irq);
	if (ret < 0) {
		pr_err("%s: failed enable irq wake %d\n", __func__,
						fg_data->irq);
		goto err_enable_irq;
	}

#ifdef DEBUG_FUELGAUGE_POLLING
	INIT_DELAYED_WORK_DEFERRABLE(&fg_data->polling_work,
					max17047_polling_work);
	schedule_delayed_work(&fg_data->polling_work, 0);
#else
	max17047_test_read(fg_data);
#endif

	pr_info("%s: probe complete\n", __func__);

#if defined(CONFIG_TARGET_LOCALE_KOR)
#ifdef CONFIG_DEBUG_FS
	fg_data->fg_debugfs_dir =
		debugfs_create_dir("fg_debug", NULL);
	if (fg_data->fg_debugfs_dir) {
		if (!debugfs_create_file("max17047_regs", 0644,
			fg_data->fg_debugfs_dir,
			fg_data, &max17047_debugfs_fops))
			pr_err("%s : debugfs_create_file, error\n", __func__);
		if (!debugfs_create_file("default_data", 0644,
			fg_data->fg_debugfs_dir,
			fg_data, &max17047_debugfs_fops2))
			pr_err("%s : debugfs_create_file2, error\n", __func__);
	} else
		pr_err("%s : debugfs_create_dir, error\n", __func__);
#endif
#endif

	return 0;

err_enable_irq:
	free_irq(fg_data->irq, fg_data);
err_irq:
	power_supply_unregister(&fg_data->fuelgauge);
err_psy_reg_fg:
	wake_lock_destroy(&fg_data->update_wake_lock);
	mutex_destroy(&fg_data->irq_lock);
	kfree(fg_data);
	return ret;
}
コード例 #25
0
ファイル: twl4030-usb.c プロジェクト: matianfu/kunlun-kernel
static int __devinit twl4030_usb_probe(struct platform_device *pdev)
{
	struct twl4030_usb_data *pdata = pdev->dev.platform_data;
	struct twl4030_usb	*twl;
	int			status, err;

#ifdef CONFIG_BOOTCASE_VIATELECOM
       /*disable USB when boot by charger, then do nothing*/
       extern const char * get_bootcase(void);
       if(!strncmp(get_bootcase(), "charger", strlen("charger"))){
           return 0;
       }
#endif

	if (!pdata) {
		dev_dbg(&pdev->dev, "platform_data not available\n");
		return -EINVAL;
	}

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

	twl->dev		= &pdev->dev;
	twl->irq		= platform_get_irq(pdev, 0);
	twl->otg.dev		= twl->dev;
	twl->otg.label		= "twl4030";
	twl->otg.set_host	= twl4030_set_host;
	twl->otg.set_peripheral	= twl4030_set_peripheral;
	twl->otg.set_suspend	= twl4030_set_suspend;
	twl->usb_mode		= pdata->usb_mode;
	twl->asleep		= 1;

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl4030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		kfree(twl);
		return err;
	}
	otg_set_transceiver(&twl->otg);

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier);

	/* Our job is to use irqs and status from the power module
	 * to keep the transceiver disabled when nothing's connected.
	 *
	 * FIXME we actually shouldn't start enabling it until the
	 * USB controller drivers have said they're ready, by calling
	 * set_host() and/or set_peripheral() ... OTG_capable boards
	 * need both handles, otherwise just one suffices.
	 */
	twl->irq_enabled = true;
	status = request_threaded_irq(twl->irq, NULL, twl4030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
			"twl4030_usb", twl);
	if (status < 0) {
		dev_dbg(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq, status);
		kfree(twl);
		return status;
	}

	/* The IRQ handler just handles changes from the previous states
	 * of the ID and VBUS pins ... in probe() we must initialize that
	 * previous state.  The easy way:  fake an IRQ.
	 *
	 * REVISIT:  a real IRQ might have happened already, if PREEMPT is
	 * enabled.  Else the IRQ may not yet be configured or enabled,
	 * because of scheduling delays.
	 */
	twl4030_usb_irq(twl->irq, twl);

	dev_info(&pdev->dev, "Initialized TWL4030 USB module\n");
	return 0;
}
コード例 #26
0
static int cypress_touchkey_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct device *dev = &client->dev;
	struct input_dev *input_dev;
	struct cypress_touchkey_devdata *devdata;
	u8 data[3];
	int err;
	int cnt;
#if defined(TOUCH_UPDATE)
	int ret;
	int retry = 10;
#endif

	if (!dev->platform_data) {
		dev_err(dev, "%s: Platform data is NULL\n", __func__);
		return -EINVAL;
	}

	devdata = kzalloc(sizeof(*devdata), GFP_KERNEL);
	if (devdata == NULL) {
		dev_err(dev, "%s: failed to create our state\n", __func__);
		return -ENODEV;
	}

	devdata->client = client;
	i2c_set_clientdata(client, devdata);

	devdata->pdata = client->dev.platform_data;
	if (!devdata->pdata->keycode) {
		dev_err(dev, "%s: Invalid platform data\n", __func__);
		err = -EINVAL;
		goto err_null_keycodes;
	}

	strlcpy(devdata->client->name, DEVICE_NAME, I2C_NAME_SIZE);

	input_dev = input_allocate_device();
	if (!input_dev) {
		err = -ENOMEM;
		goto err_input_alloc_dev;
	}

	devdata->input_dev = input_dev;
	dev_set_drvdata(&input_dev->dev, devdata);
	input_dev->name = DEVICE_NAME;
	input_dev->id.bustype = BUS_HOST;

	for (cnt = 0; cnt < devdata->pdata->keycode_cnt; cnt++)
		input_set_capability(input_dev, EV_KEY,
					devdata->pdata->keycode[cnt]);

	err = input_register_device(input_dev);
	if (err)
		goto err_input_reg_dev;

	devdata->is_powering_on = true;

	devdata->pdata->touchkey_onoff(TOUCHKEY_ON);

	err = i2c_master_recv(client, data, sizeof(data));
	if (err < sizeof(data)) {
		if (err >= 0)
			err = -EIO;
		dev_err(dev, "%s: error reading hardware version\n", __func__);
		goto err_read;
	}

	dev_info(dev, "%s: hardware rev1 = %#02x, rev2 = %#02x\n", __func__,
				data[1], data[2]);

	devdata->backlight_on = BACKLIGHT_ON;
	devdata->backlight_off = BACKLIGHT_OFF;

	devdata->has_legacy_keycode = 1;
#if 0
	err = i2c_touchkey_write_byte(devdata, devdata->backlight_on);
	if (err) {
		dev_err(dev, "%s: touch keypad backlight on failed\n",
				__func__);
		goto err_backlight_on;
	}
#endif
	if (request_threaded_irq(client->irq, touchkey_interrupt_handler,
				touchkey_interrupt_thread, IRQF_TRIGGER_FALLING,
				DEVICE_NAME, devdata)) {
		dev_err(dev, "%s: Can't allocate irq.\n", __func__);
		goto err_req_irq;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	devdata->early_suspend.suspend = cypress_touchkey_early_suspend;
	devdata->early_suspend.resume = cypress_touchkey_early_resume;
#endif
	register_early_suspend(&devdata->early_suspend);

	devdata->is_powering_on = false;
#if defined(TOUCH_UPDATE)
	ret = misc_register(&touchkey_update_device);
	if (ret) {
		printk("%s misc_register fail\n", __FUNCTION__);
		goto err_misc_reg;
	}

	dev_set_drvdata(touchkey_update_device.this_device, devdata);

	if (device_create_file
	    (touchkey_update_device.this_device, &dev_attr_touch_version) < 0) {
		printk("%s device_create_file fail dev_attr_touch_version\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_touch_version.attr.name);
	}

	if (device_create_file
	    (touchkey_update_device.this_device, &dev_attr_touch_update) < 0) {
		printk("%s device_create_file fail dev_attr_touch_update\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_touch_update.attr.name);
	}

	if (device_create_file
	    (touchkey_update_device.this_device, &dev_attr_brightness) < 0) {
		printk("%s device_create_file fail dev_attr_touch_update\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_brightness.attr.name);
	}

	if (device_create_file
	    (touchkey_update_device.this_device,
	     &dev_attr_enable_disable) < 0) {
		printk("%s device_create_file fail dev_attr_touch_update\n",
		       __FUNCTION__);
		pr_err("Failed to create device file(%s)!\n",
		       dev_attr_enable_disable.attr.name);
	}

	touchkey_wq = create_singlethread_workqueue(DEVICE_NAME);
	if (!touchkey_wq)
		goto err_create_wq;

	while (retry--) {
		if (get_touchkey_firmware(data) == 0)	//melfas need delay for multiple read
			break;
	}
	printk("%s F/W version: 0x%x, Module version:0x%x\n", __FUNCTION__,
	       data[1], data[2]);
#endif

	return 0;

err_create_wq:
#if defined(TOUCH_UPDATE)
	misc_deregister(&touchkey_update_device);
#endif
err_misc_reg:
err_req_irq:
err_backlight_on:
err_read:
	devdata->pdata->touchkey_onoff(TOUCHKEY_OFF);
	input_unregister_device(input_dev);
	goto err_input_alloc_dev;
err_input_reg_dev:
	input_free_device(input_dev);
err_input_alloc_dev:
err_null_keycodes:
	kfree(devdata);
	return err;
}