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); }
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; }
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; }
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]); } }
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); }
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; }
/** * 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; }
/** * 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; }
/** * 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; }
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; }
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; }