Ejemplo n.º 1
0
static int i2c_camera_power(struct device *dev, int on)
{
	int res, ret = 0;

	pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");

	res = devm_gpio_request(dev, camera_power_pin, "ov2640_power");
	if (res < 0) {
		printk("can't request ov2640_power pin\n");
		return -1;
	}

	res = devm_gpio_request(dev, camera_reset_pin, "ov2640_reset");
	if (res < 0) {
		printk("can't request ov2640_reset pin\n");
		devm_gpio_free(dev, camera_power_pin);
		return -1;
	}

	/* enable or disable the camera */
	res = gpio_direction_output(camera_power_pin, !on);
	if (res < 0) {
		printk("can't request output direction for ov2640_power pin\n");
		ret = -1;
		goto out;
	}

	if (!on)
		goto out;

	/* If enabled, give a reset impulse */
	res = gpio_direction_output(camera_reset_pin, 0);
	if (res < 0) {
		printk("can't request output direction for ov2640_reset pin\n");
		ret = -1;
		goto out;
	}
	msleep(20);
	res = gpio_direction_output(camera_reset_pin, 1);
	if (res < 0) {
		printk("can't request output direction for ov2640_reset pin\n");
		ret = -1;
		goto out;
	}
	msleep(100);

out:
	devm_gpio_free(dev, camera_reset_pin);
	devm_gpio_free(dev, camera_power_pin);
	return ret;
}
Ejemplo n.º 2
0
static void poweroff_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);

	if (apb->init_disabled || apb->state == ARCHE_PLATFORM_STATE_OFF)
		return;

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
			gpio_is_valid(apb->spi_en_gpio))
		devm_gpio_free(dev, apb->spi_en_gpio);

	/* disable the clock */
	if (gpio_is_valid(apb->clk_en_gpio))
		gpio_set_value(apb->clk_en_gpio, 0);

	if (!IS_ERR(apb->vcore) && regulator_is_enabled(apb->vcore) > 0)
		regulator_disable(apb->vcore);

	if (!IS_ERR(apb->vio) && regulator_is_enabled(apb->vio) > 0)
		regulator_disable(apb->vio);

	/* As part of exit, put APB back in reset state */
	assert_reset(apb->resetn_gpio);
	apb->state = ARCHE_PLATFORM_STATE_OFF;

	/* TODO: May have to send an event to SVC about this exit */
}
Ejemplo n.º 3
0
static int standby_boot_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);

	if (apb->init_disabled)
		return 0;

	/* Even if it is in OFF state, then we do not want to change the state */
	if (apb->state == ARCHE_PLATFORM_STATE_STANDBY ||
			apb->state == ARCHE_PLATFORM_STATE_OFF)
		return 0;

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
			gpio_is_valid(apb->spi_en_gpio))
		devm_gpio_free(dev, apb->spi_en_gpio);

	/*
	 * As per WDM spec, do nothing
	 *
	 * Pasted from WDM spec,
	 *  - A falling edge on POWEROFF_L is detected (a)
	 *  - WDM enters standby mode, but no output signals are changed
	 */

	/* TODO: POWEROFF_L is input to WDM module  */
	apb->state = ARCHE_PLATFORM_STATE_STANDBY;
	return 0;
}
Ejemplo n.º 4
0
static int sdhci_acpi_add_own_cd(struct device *dev, int gpio,
				 struct mmc_host *mmc)
{
	unsigned long flags;
	int err, irq;

	if (gpio < 0) {
		err = gpio;
		goto out;
	}

	err = devm_gpio_request_one(dev, gpio, GPIOF_DIR_IN, "sd_cd");
	if (err)
		goto out;

	irq = gpio_to_irq(gpio);
	if (irq < 0) {
		err = irq;
		goto out_free;
	}

	flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
	err = devm_request_irq(dev, irq, sdhci_acpi_sd_cd, flags, "sd_cd", mmc);
	if (err)
		goto out_free;

	return 0;

out_free:
	devm_gpio_free(dev, gpio);
out:
	dev_warn(dev, "failed to setup card detect wake up\n");
	return err;
}
Ejemplo n.º 5
0
static void __exit tgpio_exit(void)
{
	struct private_data *p = dev_get_drvdata(&device);
	devm_gpio_free(&device, p->gpio_num);
	del_timer(&p->timeout);
	device_remove_file(&device, &dev_attr_timer_timeout);
	device_unregister(&device);
}
Ejemplo n.º 6
0
static int mcuio_dio_probe(struct mcuio_device *mdev)
{
	struct mcuio_shld_i2c_info *i;
	int cnt;
	int ret;
	struct mcuio_shld_data *data;

	dev_dbg(&mdev->dev, "%s entered\n", __func__);

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

	dev_set_drvdata(&mdev->dev, data);

	/* Apply module_param values to platform_data when needed */
	pca9555_plat.gpio_base = pca9555_base;

	data->i2c_adap = mcuio_get_i2c_adapter(mdev);

	if (!data->i2c_adap) {
		dev_err(&mdev->dev, "error setting up i2c adapter\n");
		return -ENODEV;
	}

	data->i2c_info = i2c_lst;
	data->i2c_cnt = ARRAY_SIZE(i2c_lst);

	/* Register all devices in Digital IO shield */
	for (cnt = 0; cnt < data->i2c_cnt; cnt++) {
		i = &data->i2c_info[cnt];
		i->info.addr = *i->paddr;

		/* HACK this is needed to enable pullup */
		ret = devm_gpio_request_one(&mdev->dev, i->gpio_irq, GPIOF_DIR_IN,
				    "digitalio-shield");
		if (ret < 0)
			return ret;
		gpio_direction_output(i->gpio_irq, 1);
		gpio_direction_input(i->gpio_irq);
		devm_gpio_free(&mdev->dev, i->gpio_irq);

		i->info.irq = (i->gpio_irq >= 0) ?
			gpio_to_irq(i->gpio_irq) : 0;

		i->i2c_client = i2c_new_device(data->i2c_adap, &i->info);
		if (!i->i2c_client)
			dev_err(&mdev->dev,
				"i2c_new_device %s failed\n", i->info.type);
	}

	dev_dbg(&mdev->dev, "%s returns ok\n", __func__);

	return 0;
}
Ejemplo n.º 7
0
static int de1soc_audio_remove(struct platform_device *pdev)
{
	struct snd_soc_card *card = platform_get_drvdata(pdev);

	if (gpio_is_valid(i2c_mux_gpio))
		devm_gpio_free(&pdev->dev, i2c_mux_gpio);

	snd_soc_unregister_card(card);

	return 0;
}
/**
 * mmc_gpio_free_ro - free the write-protection gpio
 * @host: mmc host
 *
 * It's provided only for cases that client drivers need to manually free
 * up the write-protection gpio requested by mmc_gpio_request_ro().
 */
void mmc_gpio_free_ro(struct mmc_host *host)
{
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int gpio;

	if (!ctx || !gpio_is_valid(ctx->ro_gpio))
		return;

	gpio = ctx->ro_gpio;
	ctx->ro_gpio = -EINVAL;

	devm_gpio_free(&host->class_dev, gpio);
}
Ejemplo n.º 9
0
/**
 * mmc_gpio_free_ro - free the write-protection gpio
 * @host: mmc host
 *
 * It's provided only for cases that client drivers need to manually free
 * up the write-protection gpio requested by mmc_gpio_request_ro().
 */
void mmc_gpio_free_ro(struct mmc_host *host)
{
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int gpio;

	if (!ctx || !ctx->ro_gpio)
		return;

	gpio = desc_to_gpio(ctx->ro_gpio);
	ctx->ro_gpio = NULL;

	devm_gpio_free(&host->class_dev, gpio);
}
Ejemplo n.º 10
0
/*
 * Note: Please do not modify the below sequence, as it is as per the spec
 */
static int coldboot_seq(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev);
	int ret;

	if (apb->init_disabled ||
			apb->state == ARCHE_PLATFORM_STATE_ACTIVE)
		return 0;

	/* Hold APB in reset state */
	assert_reset(apb->resetn_gpio);

	if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING &&
			gpio_is_valid(apb->spi_en_gpio))
		devm_gpio_free(dev, apb->spi_en_gpio);

	/* Enable power to APB */
	if (!IS_ERR(apb->vcore)) {
		ret = regulator_enable(apb->vcore);
		if (ret) {
			dev_err(dev, "failed to enable core regulator\n");
			return ret;
		}
	}

	if (!IS_ERR(apb->vio)) {
		ret = regulator_enable(apb->vio);
		if (ret) {
			dev_err(dev, "failed to enable IO regulator\n");
			return ret;
		}
	}

	apb_bootret_deassert(dev);

	/* On DB3 clock was not mandatory */
	if (gpio_is_valid(apb->clk_en_gpio))
		gpio_set_value(apb->clk_en_gpio, 1);

	usleep_range(100, 200);

	/* deassert reset to APB : Active-low signal */
	deassert_reset(apb->resetn_gpio);

	apb->state = ARCHE_PLATFORM_STATE_ACTIVE;

	return 0;
}
/**
 * mmc_gpio_free_cd - free the card-detection gpio
 * @host: mmc host
 *
 * It's provided only for cases that client drivers need to manually free
 * up the card-detection gpio requested by mmc_gpio_request_cd().
 */
void mmc_gpio_free_cd(struct mmc_host *host)
{
	struct mmc_gpio *ctx = host->slot.handler_priv;
	int gpio;

	if (!ctx || !gpio_is_valid(ctx->cd_gpio))
		return;

	if (host->slot.cd_irq >= 0) {
		devm_free_irq(&host->class_dev, host->slot.cd_irq, host);
		host->slot.cd_irq = -EINVAL;
	}

	gpio = ctx->cd_gpio;
	ctx->cd_gpio = -EINVAL;

	devm_gpio_free(&host->class_dev, gpio);
}
static int hinge_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	struct hinge_data *data = NULL;
	struct hinge_platform_data *pdata;
	int err = 0;
	int value;
	int retries;
	int bootcfg_value, reset_value;
	int gpio_init_flags;

	dev_info(&client->dev, "%s: enter\n", __func__);

#if 0
	if (client->addr != HINGE_SLAVE_ADDRESS) {
		dev_err(&client->dev, "Unexpected slave address 0x%02x\n",
				client->addr);
		err = -EINVAL;
		goto error_1;
	}
#endif

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->dev, "Missing platform data.\n");
		err = -EINVAL;
		goto error_1;
	}

	data = kzalloc(sizeof(struct hinge_data), GFP_KERNEL);
	if (!data) {
		err = -ENOMEM;
		goto error_1;
	}

	i2c_set_clientdata(client, data);
	data->dev = &client->dev;

	data->idev = input_allocate_device();
	CHECK_ERROR(!data->idev, error_2, "Failed to allocate input device!\n");

	data->idev->name = HINGE_NAME "-keys";
	data->idev->phys = HINGE_NAME "-keys/input0";
	data->idev->id.bustype = BUS_I2C;
	data->idev->dev.parent = &client->dev;

	set_bit(EV_KEY, data->idev->evbit);
	set_bit(KEY_CAMERA, data->idev->keybit);
	set_bit(KEY_CAMERA_FOCUS, data->idev->keybit);

	set_bit(EV_SW, data->idev->evbit);
	set_bit(SW_RFKILL_ALL, data->idev->swbit);

	err = input_register_device(data->idev);
	CHECK_ERROR(err, error_3, "Failed to register input device: %d\n", err);

	wake_lock_init(&data->wakelock, WAKE_LOCK_SUSPEND, "hinge_wakelock");

	dev_info(&client->dev, "Defined GPIOs\n");
	dev_info(&client->dev, "reset_gpio: %d\n", pdata->reset_gpio);
	dev_info(&client->dev, "bootcfg_gpio: %d\n", pdata->bootcfg_gpio);
	dev_info(&client->dev, "preview_gpio: %d\n", pdata->irq_preview_gpio);
	dev_info(&client->dev, "photo_gpio: %d\n", pdata->irq_photo_gpio);
	dev_info(&client->dev, "hinge_gpio: %d\n", pdata->irq_hinge_gpio);

	err = -EINVAL;
	CHECK_ERROR(pdata->irq_hinge_gpio == -1, error_4, "hinge_gpio is not defined\n");
	data->irq_hinge = gpio_to_irq(pdata->irq_hinge_gpio);

	CHECK_ERROR(pdata->irq_photo_gpio == -1, error_4, "photo_gpio is not defined\n");
	data->irq_photo = gpio_to_irq(pdata->irq_photo_gpio);

	CHECK_ERROR(pdata->irq_preview_gpio == -1, error_4, "preview_gpio is not defined\n");
	data->irq_preview = gpio_to_irq(pdata->irq_preview_gpio);

	data->irq_hinge = gpio_to_irq(pdata->irq_hinge_gpio);
	data->irq_photo = gpio_to_irq(pdata->irq_photo_gpio);
	data->irq_preview = gpio_to_irq(pdata->irq_preview_gpio);

	data->hinge_gpio = pdata->irq_hinge_gpio;
	data->photo_gpio = pdata->irq_photo_gpio;
	data->preview_gpio = pdata->irq_preview_gpio;
	data->bootcfg_gpio = pdata->bootcfg_gpio;
	data->reset_gpio = pdata->reset_gpio;
	data->active_polarity = pdata->active_polarity;

	dev_info(&client->dev, "active_polarity=%d\n", data->active_polarity);

	/* reset and bootcfg initial config depends on polarity */
	gpio_init_flags = data->active_polarity ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;

	err = -EINVAL;
	CHECK_ERROR(data->bootcfg_gpio == -1, error_4, "bootcfg_gpio is not defined\n");
	err = devm_gpio_request_one(data->dev, data->bootcfg_gpio, gpio_init_flags, "mcu_bootcfg0");
	CHECK_ERROR(err, error_4, "Failed to request bootcfg gpio (%d): %d\n", data->bootcfg_gpio, err);

	err = -EINVAL;
	CHECK_ERROR(data->reset_gpio == -1, error_5, "reset_gpio is not defined\n");
	err = devm_gpio_request_one(data->dev, data->reset_gpio, gpio_init_flags, "mcu_reset");
	CHECK_ERROR(err, error_5, "Failed to request reset gpio (%d): %d\n", data->reset_gpio, err);

	err = -EINVAL;
	CHECK_ERROR(data->hinge_gpio == -1, error_6, "hinge_gpio is not defined\n");
	err = devm_gpio_request_one(data->dev, data->hinge_gpio, GPIOF_IN, "mcu_hinge");
	CHECK_ERROR(err, error_6, "Failed to request hinge gpio (%d): %d\n", data->hinge_gpio, err);

	err = -EINVAL;
	CHECK_ERROR(data->photo_gpio == -1, error_7, "photo_gpio is not defined\n");
	err = devm_gpio_request_one(data->dev, data->photo_gpio, GPIOF_IN, "mcu_photo");
	CHECK_ERROR(err, error_7, "Failed to request photo gpio (%d): %d\n", data->photo_gpio, err);

	err = -EINVAL;
	CHECK_ERROR(data->preview_gpio == -1, error_8, "preview_gpio is not defined\n");
	err = devm_gpio_request_one(data->dev, data->preview_gpio, GPIOF_IN, "mcu_preview");
	CHECK_ERROR(err, error_8, "Failed to request preview gpio (%d): %d\n", data->preview_gpio, err);

	err = request_threaded_irq(data->irq_hinge, NULL, hinge_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_NO_SUSPEND,
			HINGE_NAME "-hinge", data);
	CHECK_ERROR(err, error_9, "Failed to register hinge irq %d (gpio %d): %d\n",
				data->irq_hinge, pdata->irq_hinge_gpio, err);

	err = request_threaded_irq(data->irq_photo, NULL, hinge_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_NO_SUSPEND,
			HINGE_NAME "-photo", data);
	CHECK_ERROR(err, error_10, "Failed to register photo irq %d (gpio %d): %d\n",
				data->irq_photo, pdata->irq_photo_gpio, err);

	err = request_threaded_irq(data->irq_preview, NULL, hinge_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_NO_SUSPEND,
			HINGE_NAME "-preview", data);
	CHECK_ERROR(err, error_11, "Failed to register preview irq %d (gpio %d): %d\n",
				data->irq_preview, pdata->irq_preview_gpio, err);

	err = sysfs_create_group(&data->dev->kobj, &hinge_attr_group);
	CHECK_ERROR(err, error_12, "Failed to create sysfs nodes: %d\n", err);

	/* read initial values of bootcfg and reset */
	bootcfg_value = hinge_get_bootcfg(data);
	reset_value = hinge_get_reset(data);

	dev_warn(&client->dev, "Initial values: bootcfg=%d reset=%d\n", bootcfg_value, reset_value);

	retries = 10;
	do {
		hinge_determine_status(data);
	} while (data->mcu_status == MCU_STATUS_ERROR && retries--);

	/* if the MCU still can't be reached, try resetting it between attempts */
	hinge_set_bootcfg(data, false);

	retries = 5;
	while (data->mcu_status == MCU_STATUS_ERROR && retries--) {
		hinge_set_reset(data, true);
		usleep_range(10000, 10500);
		hinge_set_reset(data, false);
		usleep_range(10000, 10500);

		hinge_determine_status(data);
	}

	if (data->mcu_status == MCU_STATUS_RESET) {
		dev_info(data->dev, "MCU in reset at boot\n");

		/* make sure the MCU is not left in reset */
		retries = 10;
		do {
			hinge_set_bootcfg(data, false);
			hinge_set_reset(data, false);

			usleep_range(10000, 10500);
			hinge_determine_status(data);
		} while ((data->mcu_status == MCU_STATUS_RESET || data->mcu_status == MCU_STATUS_ERROR)
				&& retries--);

		if (data->mcu_status == MCU_STATUS_RESET)
			dev_err(data->dev, "Failed to take the MCU out of reset\n");
	}

	if (data->mcu_status == MCU_STATUS_BOOTLOADER) {
		dev_info(data->dev, "MCU in bootloader at boot\n");

		hinge_bl_jumpstart(data);

		usleep_range(10000, 10500);
		hinge_determine_status(data);

		if (data->mcu_status != MCU_STATUS_RUNNING)
			dev_err(data->dev, "Failed to jumpstart the MCU\n");
	}

	if (data->mcu_status == MCU_STATUS_RUNNING) {
		err = hinge_read_reg(data, REG_FIRMWARE_REVISION, &value);
		if (err)
			dev_warn(&client->dev, "WARNING: Failed to read MCU firmware revision: %d\n", err);
		else
			dev_info(&client->dev, "Firmware revision is %08x\n", value);

		/* dump programmed thresholds */
		hinge_read_reg(data, REG_HALL_HINGE_CLOSED, &value);
		dev_info(data->dev, "hinge_closed=%08x\n", value);

		hinge_read_reg(data, REG_HALL_HINGE_OPENED, &value);
		dev_info(data->dev, "hinge_opened=%08x\n", value);

		hinge_read_reg(data, REG_HALL_PREVIEW_PRESSED, &value);
		dev_info(data->dev, "preview_pressed=%08x\n", value);

		hinge_read_reg(data, REG_HALL_PREVIEW_RELEASED, &value);
		dev_info(data->dev, "preview_released=%08x\n", value);

		hinge_read_reg(data, REG_HALL_PHOTO_PRESSED, &value);
		dev_info(data->dev, "photo_pressed=%08x\n", value);

		hinge_read_reg(data, REG_HALL_PHOTO_RELEASED, &value);
		dev_info(data->dev, "photo_released=%08x\n", value);

		/* send initial hinge state event */
		handle_hinge_event(data, true);
	} else if (data->mcu_status == MCU_STATUS_ERROR) {
		dev_info(data->dev, "MCU in unknown state at boot, holding it in reset for safety.\n");
		hinge_set_bootcfg(data, false);
		hinge_set_reset(data, true);
	}

	dev_info(&client->dev, "%s: exit\n", __func__);

	return 0;

/*
error_13:
	sysfs_remove_group(&data->dev->kobj, &hinge_attr_group);
*/
error_12:
	free_irq(data->irq_preview, data);
error_11:
	free_irq(data->irq_photo, data);
error_10:
	free_irq(data->irq_hinge, data);
error_9:
	devm_gpio_free(data->dev, data->preview_gpio);
error_8:
	devm_gpio_free(data->dev, data->photo_gpio);
error_7:
	devm_gpio_free(data->dev, data->hinge_gpio);
error_6:
	devm_gpio_free(data->dev, data->reset_gpio);
error_5:
	devm_gpio_free(data->dev, data->bootcfg_gpio);
error_4:
	input_unregister_device(data->idev);
error_3:
	input_free_device(data->idev);
error_2:
	i2c_set_clientdata(client, NULL);
	wake_lock_destroy(&data->wakelock);
	kfree(data);
error_1:
	dev_info(&client->dev, "%s: error: %d\n", __func__, err);

	return err;
}