예제 #1
0
파일: pimhyp3.c 프로젝트: procount/pinn
static void lcd_init(struct pimhyp3_ts_data *ts)
{
    int count;
    int x;
    //setup_pins

    gpiod_direction_output(ts->gpiod_cs,1);
    gpiod_direction_output(ts->gpiod_int,1);    //CLK = output
    gpiod_direction_output(ts->gpiod_mosi,0);

    //setup_lcd
    count = sizeof(commands) / sizeof(int32_t);
    for(x = 0; x < count; x++){
        int32_t command = commands[x];
        if(command == -1){
            mdelay(mWAIT);
            continue;
        }
        write(ts,(uint16_t)command);
    }

    //cleanup_pins
    // Return the touch interrupt pin to a usable state
    gpiod_direction_input(ts->gpiod_int);
}
예제 #2
0
static int mlx90614_wakeup(struct mlx90614_data *data)
{
	if (!data->wakeup_gpio) {
		dev_dbg(&data->client->dev, "Wake-up disabled");
		return -ENOSYS;
	}

	dev_dbg(&data->client->dev, "Requesting wake-up");

	i2c_lock_adapter(data->client->adapter);
	gpiod_direction_output(data->wakeup_gpio, 0);
	msleep(MLX90614_TIMING_WAKEUP);
	gpiod_direction_input(data->wakeup_gpio);
	i2c_unlock_adapter(data->client->adapter);

	data->ready_timestamp = jiffies +
			msecs_to_jiffies(MLX90614_TIMING_STARTUP);

	/*
	 * Quirk: the i2c controller may get confused right after the
	 * wake-up signal has been sent.  As a workaround, do a dummy read.
	 * If the read fails, the controller will probably be reset so that
	 * further reads will work.
	 */
	i2c_smbus_read_word_data(data->client, MLX90614_CONFIG);

	return 0;
}
예제 #3
0
static int sdhci_acpi_add_own_cd(struct device *dev, struct mmc_host *mmc)
{
	struct gpio_desc *desc;
	unsigned long flags;
	int err, irq;

	desc = devm_gpiod_get_index(dev, "sd_cd", 0);
	if (IS_ERR(desc)) {
		err = PTR_ERR(desc);
		goto out;
	}

	err = gpiod_direction_input(desc);
	if (err)
		goto out_free;

	irq = gpiod_to_irq(desc);
	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_gpiod_put(dev, desc);
out:
	dev_warn(dev, "failed to setup card detect wake up\n");
	return err;
}
예제 #4
0
파일: sfp.c 프로젝트: mkrufky/linux
static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state)
{
	if (state & SFP_F_PRESENT) {
		/* If the module is present, drive the signals */
		if (sfp->gpio[GPIO_TX_DISABLE])
			gpiod_direction_output(sfp->gpio[GPIO_TX_DISABLE],
						state & SFP_F_TX_DISABLE);
		if (state & SFP_F_RATE_SELECT)
			gpiod_direction_output(sfp->gpio[GPIO_RATE_SELECT],
						state & SFP_F_RATE_SELECT);
	} else {
		/* Otherwise, let them float to the pull-ups */
		if (sfp->gpio[GPIO_TX_DISABLE])
			gpiod_direction_input(sfp->gpio[GPIO_TX_DISABLE]);
		if (state & SFP_F_RATE_SELECT)
			gpiod_direction_input(sfp->gpio[GPIO_RATE_SELECT]);
	}
}
예제 #5
0
static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
{
	struct mdio_gpio_info *bitbang =
		container_of(ctrl, struct mdio_gpio_info, ctrl);

	if (bitbang->mdo) {
		/* Separate output pin. Always set its value to high
		 * when changing direction. If direction is input,
		 * assume the pin serves as pull-up. If direction is
		 * output, the default value is high.
		 */
		gpiod_set_value_cansleep(bitbang->mdo, 1);
		return;
	}

	if (dir)
		gpiod_direction_output(bitbang->mdio, 1);
	else
		gpiod_direction_input(bitbang->mdio);
}
예제 #6
0
파일: edp_ctrl.c 프로젝트: 3bsa/linux
static int edp_gpio_config(struct edp_ctrl *ctrl)
{
	struct device *dev = &ctrl->pdev->dev;
	int ret;

	ctrl->panel_hpd_gpio = devm_gpiod_get(dev, "panel-hpd");
	if (IS_ERR(ctrl->panel_hpd_gpio)) {
		ret = PTR_ERR(ctrl->panel_hpd_gpio);
		ctrl->panel_hpd_gpio = NULL;
		pr_err("%s: cannot get panel-hpd-gpios, %d\n", __func__, ret);
		return ret;
	}

	ret = gpiod_direction_input(ctrl->panel_hpd_gpio);
	if (ret) {
		pr_err("%s: Set direction for hpd failed, %d\n", __func__, ret);
		return ret;
	}

	ctrl->panel_en_gpio = devm_gpiod_get(dev, "panel-en");
	if (IS_ERR(ctrl->panel_en_gpio)) {
		ret = PTR_ERR(ctrl->panel_en_gpio);
		ctrl->panel_en_gpio = NULL;
		pr_err("%s: cannot get panel-en-gpios, %d\n", __func__, ret);
		return ret;
	}

	ret = gpiod_direction_output(ctrl->panel_en_gpio, 0);
	if (ret) {
		pr_err("%s: Set direction for panel_en failed, %d\n",
				__func__, ret);
		return ret;
	}

	DBG("gpio on");

	return 0;
}
예제 #7
0
/**
 * mmc_gpiod_request_cd - request a gpio descriptor for card-detection
 * @host: mmc host
 * @con_id: function within the GPIO consumer
 * @idx: index of the GPIO to obtain in the consumer
 * @override_active_level: ignore %GPIO_ACTIVE_LOW flag
 * @debounce: debounce time in microseconds
 *
 * Use this function in place of mmc_gpio_request_cd() to use the GPIO
 * descriptor API.  Note that it is paired with mmc_gpiod_free_cd() not
 * mmc_gpio_free_cd().  Note also that it must be called prior to mmc_add_host()
 * otherwise the caller must also call mmc_gpiod_request_cd_irq().
 *
 * Returns zero on success, else an error.
 */
int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
			 unsigned int idx, bool override_active_level,
			 unsigned int debounce)
{
	struct mmc_gpio *ctx;
	struct gpio_desc *desc;
	int ret;

	ret = mmc_gpio_alloc(host);
	if (ret < 0)
		return ret;

	ctx = host->slot.handler_priv;

	if (!con_id)
		con_id = ctx->cd_label;

	desc = devm_gpiod_get_index(host->parent, con_id, idx);
	if (IS_ERR(desc))
		return PTR_ERR(desc);

	ret = gpiod_direction_input(desc);
	if (ret < 0)
		return ret;

	if (debounce) {
		ret = gpiod_set_debounce(desc, debounce);
		if (ret < 0)
			return ret;
	}

	ctx->override_cd_active_level = override_active_level;
	ctx->cd_gpio = desc;

	return 0;
}
예제 #8
0
파일: pimhyp3.c 프로젝트: procount/pinn
/**
 * pimhyp3_get_gpio_config - Get GPIO config from ACPI/DT
 *
 * @ts: pimhyp3_ts_data pointer
 */
static int pimhyp3_get_gpio_config(struct pimhyp3_ts_data *ts)
{
    int error;
    struct device *dev;
    struct gpio_desc *gpiod;
    u32 sizeX, sizeY, refreshRate;

    if (!ts->client)
        return -EINVAL;
    dev = &ts->client->dev;

    /* Get the interrupt GPIO pin description */
    gpiod = devm_gpiod_get(dev, PIMHYP3_GPIO_INT_NAME, GPIOD_IN);
    if (IS_ERR(gpiod)) {
        error = PTR_ERR(gpiod);
        if (error != -EPROBE_DEFER)
            dev_dbg(dev, "Failed to get %s GPIO: %d\n",
                PIMHYP3_GPIO_INT_NAME, error);
        return error;
    }

    /* Ensure the correct direction is set because this pin is also used to
     * program the LCD controller
     */
    ts->gpiod_int = gpiod;
    gpiod_direction_input(ts->gpiod_int);

    /* Get the MOSI GPIO pin description */
    gpiod = devm_gpiod_get(dev, PIMHYP3_GPIO_MOSI_NAME, GPIOD_OUT_LOW);
    if (IS_ERR(gpiod)) {
        error = PTR_ERR(gpiod);
        if (error != -EPROBE_DEFER)
            dev_dbg(dev, "Failed to get %s GPIO: %d\n",
                PIMHYP3_GPIO_MOSI_NAME, error);
        return error;
    }

    ts->gpiod_mosi = gpiod;

    /* Get the CS GPIO pin description */
    gpiod = devm_gpiod_get(dev, PIMHYP3_GPIO_CS_NAME, GPIOD_OUT_HIGH);
    if (IS_ERR(gpiod)) {
        error = PTR_ERR(gpiod);
        if (error != -EPROBE_DEFER)
            dev_dbg(dev, "Failed to get %s GPIO: %d\n",
                PIMHYP3_GPIO_CS_NAME, error);
        return error;
    }

    ts->gpiod_cs = gpiod;


    ts->id = 0x1001;
    ts->version=0x0101;

    ts->last_numTouches=0;
    ts->max_touch_num=2;
    ts->abs_x_max = PIMHYP3_MAX_WIDTH;
    ts->abs_y_max = PIMHYP3_MAX_HEIGHT;
    ts->use_poll = false;
    ts->int_trigger_type = PIMHYP3_INT_TRIGGER;

    // Read DT configuration parameters
    ts->X2Y = device_property_read_bool(&ts->client->dev,
                                "touchscreen-x2y");
    dev_dbg(&ts->client->dev, "touchscreen-x2y %u", ts->X2Y);

    ts->use_poll = device_property_read_bool(&ts->client->dev,
                                "touchscreen-poll");
    dev_dbg(&ts->client->dev, "touchscreen-poll %u", ts->use_poll);


    if(device_property_read_u32(&ts->client->dev, "touchscreen-refresh-rate", &refreshRate))
    {
        dev_dbg(&ts->client->dev, "touchscreen-refresh-rate not found");
        ts->requestedRefreshRate = 17;
    }
    else
    {
        dev_dbg(&ts->client->dev, "touchscreen-refresh-rate found %u", refreshRate);
        ts->requestedRefreshRate = (u8)refreshRate;
    }

    if(device_property_read_u32(&ts->client->dev, "touchscreen-size-x", &sizeX))
    {
        dev_dbg(&ts->client->dev, "touchscreen-size-x not found. Using default of %u",ts->abs_x_max);
    }
    else
    {
        ts->abs_x_max = (u16)sizeX;
        dev_dbg(&ts->client->dev, "touchscreen-size-x found %u", ts->abs_x_max);
    }

    if(device_property_read_u32(&ts->client->dev, "touchscreen-size-y", &sizeY))
    {
        dev_dbg(&ts->client->dev, "touchscreen-size-y not found. Using default of %u",ts->abs_y_max);
    }
    else
    {
        ts->abs_y_max = (u16)sizeY;
        dev_dbg(&ts->client->dev, "touchscreen-size-y found %u", ts->abs_y_max);
    }

    dev_dbg(&ts->client->dev, "requested size (%u, %u)", ts->abs_x_max, ts->abs_y_max);

    ts->swapped_x_y = device_property_read_bool(&ts->client->dev, "touchscreen-swapped-x-y");
    dev_dbg(&ts->client->dev, "touchscreen-swapped-x-y %u", ts->swapped_x_y);

    ts->inverted_x = device_property_read_bool(&ts->client->dev,
                           "touchscreen-inverted-x");
    dev_dbg(&ts->client->dev, "touchscreen-inverted-x %u", ts->inverted_x);

    ts->inverted_y = device_property_read_bool(&ts->client->dev, "touchscreen-inverted-y");
    dev_dbg(&ts->client->dev, "touchscreen-inverted-y %u", ts->inverted_y);

    return 0;
}
예제 #9
0
/**
 * phy_mdm6600_device_power_on() - power on mdm6600 device
 * @ddata: device driver data
 *
 * To get the integrated USB phy in MDM6600 takes some hoops. We must ensure
 * the shared USB bootmode GPIOs are configured, then request modem start-up,
 * reset and power-up.. And then we need to recycle the shared USB bootmode
 * GPIOs as they are also used for Out of Band (OOB) wake for the USB and
 * TS 27.010 serial mux.
 */
static int phy_mdm6600_device_power_on(struct phy_mdm6600 *ddata)
{
	struct gpio_desc *mode_gpio0, *mode_gpio1, *reset_gpio, *power_gpio;
	int error = 0, wakeirq;

	mode_gpio0 = ddata->mode_gpios->desc[PHY_MDM6600_MODE0];
	mode_gpio1 = ddata->mode_gpios->desc[PHY_MDM6600_MODE1];
	reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET];
	power_gpio = ddata->ctrl_gpios[PHY_MDM6600_POWER];

	/*
	 * Shared GPIOs must be low for normal USB mode. After booting
	 * they are used for OOB wake signaling. These can be also used
	 * to configure USB flashing mode later on based on a module
	 * parameter.
	 */
	gpiod_set_value_cansleep(mode_gpio0, 0);
	gpiod_set_value_cansleep(mode_gpio1, 0);

	/* Request start-up mode */
	phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_NO_BYPASS);

	/* Request a reset first */
	gpiod_set_value_cansleep(reset_gpio, 0);
	msleep(100);

	/* Toggle power GPIO to request mdm6600 to start */
	gpiod_set_value_cansleep(power_gpio, 1);
	msleep(100);
	gpiod_set_value_cansleep(power_gpio, 0);

	/*
	 * Looks like the USB PHY needs between 2.2 to 4 seconds.
	 * If we try to use it before that, we will get L3 errors
	 * from omap-usb-host trying to access the PHY. See also
	 * phy_mdm6600_init() for -EPROBE_DEFER.
	 */
	msleep(PHY_MDM6600_PHY_DELAY_MS);
	ddata->enabled = true;

	/* Booting up the rest of MDM6600 will take total about 8 seconds */
	dev_info(ddata->dev, "Waiting for power up request to complete..\n");
	if (wait_for_completion_timeout(&ddata->ack,
			msecs_to_jiffies(PHY_MDM6600_ENABLED_DELAY_MS))) {
		if (ddata->status > PHY_MDM6600_STATUS_PANIC &&
		    ddata->status < PHY_MDM6600_STATUS_SHUTDOWN_ACK)
			dev_info(ddata->dev, "Powered up OK\n");
	} else {
		ddata->enabled = false;
		error = -ETIMEDOUT;
		dev_err(ddata->dev, "Timed out powering up\n");
	}

	/* Reconfigure mode1 GPIO as input for OOB wake */
	gpiod_direction_input(mode_gpio1);

	wakeirq = gpiod_to_irq(mode_gpio1);
	if (wakeirq <= 0)
		return wakeirq;

	error = devm_request_threaded_irq(ddata->dev, wakeirq, NULL,
					  phy_mdm6600_wakeirq_thread,
					  IRQF_TRIGGER_RISING |
					  IRQF_TRIGGER_FALLING |
					  IRQF_ONESHOT,
					  "mdm6600-wake",
					  ddata);
	if (error)
		dev_warn(ddata->dev, "no modem wakeirq irq%i: %i\n",
			 wakeirq, error);

	ddata->running = true;

	return error;
}
예제 #10
0
static int silead_ts_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct silead_ts_data *data;
	struct device *dev = &client->dev;
	int ret;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_I2C |
				     I2C_FUNC_SMBUS_READ_I2C_BLOCK |
				     I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
		dev_err(dev, "I2C functionality check failed\n");
		return -ENXIO;
	}

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	i2c_set_clientdata(client, data);
	data->client = client;

	data->fw_name = SILEAD_FW_NAME;
	data->x_max = SILEAD_X_MAX;
	data->y_max = SILEAD_Y_MAX;
	data->max_fingers = SILEAD_MAX_FINGERS;
	data->pressure = SILEAD_PRESSURE;


	/* If the IRQ is not filled by DT or ACPI subsytem
	 * try using the named GPIO */
	if (client->irq <= 0) {
		data->gpio_irq = devm_gpiod_get(dev, SILEAD_IRQ_GPIO_NAME);
		if (IS_ERR(data->gpio_irq)) {
			dev_err(dev, "IRQ GPIO request failed\n");
			return -ENODEV;
		}

		ret = gpiod_direction_input(data->gpio_irq);
		if (ret) {
			dev_err(dev, "IRQ GPIO direction set failed\n");
			return ret;
		}

		client->irq = gpiod_to_irq(data->gpio_irq);
		if (client->irq <= 0) {
			dev_err(dev, "GPIO to IRQ translation failed %d\n",
				client->irq);
			return client->irq;
		}
	}

	/* Power GPIO pin */
	if (client->dev.of_node) {
		ret = of_get_named_gpio_flags(client->dev.of_node,
					      SILEAD_PWR_GPIO_NAME, 0, NULL);
		if (ret <= 0) {
			dev_err(&client->dev, "error getting gpio for %s\n",
				SILEAD_PWR_GPIO_NAME);
			return -ENODEV;
		}

		data->gpio_power = gpio_to_desc(ret);
		if (!data->gpio_power)
			return -ENODEV;
	}

	ret = gpiod_direction_output(data->gpio_power, 0);
	if (ret) {
		dev_err(dev, "Shutdown GPIO direction set failed\n");
		return ret;
	}

	ret = silead_ts_setup(client);
	if (ret)
		return ret;

	ret = silead_ts_request_input_dev(data);
	if (ret)
		return ret;

	ret = devm_request_threaded_irq(dev, client->irq, NULL,
					silead_ts_irq_handler,
					IRQF_ONESHOT | IRQ_TYPE_EDGE_RISING,
					client->name, data);
	if (ret) {
		dev_err(dev, "IRQ request failed %d\n", ret);
		return ret;
	}

	dev_dbg(dev, "Probing succeded\n");
	return 0;
}
예제 #11
0
파일: pi433_if.c 프로젝트: avagin/linux
static int setup_gpio(struct pi433_device *device)
{
	char	name[5];
	int	retval;
	int	i;
	const irq_handler_t DIO_irq_handler[NUM_DIO] = {
		DIO0_irq_handler,
		DIO1_irq_handler
	};

	for (i = 0; i < NUM_DIO; i++) {
		/* "construct" name and get the gpio descriptor */
		snprintf(name, sizeof(name), "DIO%d", i);
		device->gpiod[i] = gpiod_get(&device->spi->dev, name,
					     0 /*GPIOD_IN*/);

		if (device->gpiod[i] == ERR_PTR(-ENOENT)) {
			dev_dbg(&device->spi->dev,
				"Could not find entry for %s. Ignoring.", name);
			continue;
		}

		if (device->gpiod[i] == ERR_PTR(-EBUSY))
			dev_dbg(&device->spi->dev, "%s is busy.", name);

		if (IS_ERR(device->gpiod[i])) {
			retval = PTR_ERR(device->gpiod[i]);
			/* release already allocated gpios */
			for (i--; i >= 0; i--) {
				free_irq(device->irq_num[i], device);
				gpiod_put(device->gpiod[i]);
			}
			return retval;
		}

		/* configure the pin */
		gpiod_unexport(device->gpiod[i]);
		retval = gpiod_direction_input(device->gpiod[i]);
		if (retval)
			return retval;

		/* configure irq */
		device->irq_num[i] = gpiod_to_irq(device->gpiod[i]);
		if (device->irq_num[i] < 0) {
			device->gpiod[i] = ERR_PTR(-EINVAL);
			return device->irq_num[i];
		}
		retval = request_irq(device->irq_num[i],
				     DIO_irq_handler[i],
				     0, /* flags */
				     name,
				     device);

		if (retval)
			return retval;

		dev_dbg(&device->spi->dev, "%s successfully configured", name);
	}

	return 0;
}