/* Enable/Disable IHF ext amplifier */ int spk_amp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { if (mc_dev_ctx->spk_pin <= 0) return 0; switch (event) { case SND_SOC_DAPM_POST_PMU: xgold_debug("%s: SND_SOC_DAPM_PRE_PMU\n", __func__); if (mc_dev_ctx->spk_pin > 0) gpiod_set_value(gpio_to_desc(mc_dev_ctx->spk_pin), 1); break; case SND_SOC_DAPM_PRE_PMD: xgold_debug("%s: SND_SOC_DAPM_PRE_PMD\n", __func__); if (mc_dev_ctx->spk_pin > 0) gpiod_set_value(gpio_to_desc(mc_dev_ctx->spk_pin), 0); break; default: break; } return 0; }
int gpiodump_show(struct seq_file *s, void *unused) { struct gpio_chip *chip = NULL; unsigned gpio; unsigned int ret = 0; if(s == NULL) { if (gpio_sleep_buffer == NULL) gpio_sleep_buffer = kmalloc(20000, GFP_ATOMIC); if (gpio_sleep_buffer == NULL) { pr_err("gpiodebug: gpiodump_show allocate memory fail\n"); return 0; } memset(gpio_sleep_buffer, 0, sizeof(gpio_sleep_buffer)); len = 0; } for (gpio = 0; gpio_is_valid(gpio); gpio++) { struct device *dev; if (chip == gpio_to_desc(gpio)->chip) continue; chip = gpio_to_desc(gpio)->chip; if (!chip) continue; if(s) { seq_printf(s, "%sGPIOs %d-%d", (char *)s->private, chip->base, chip->base + chip->ngpio - 1); dev = chip->dev; if (dev) seq_printf(s, ", %s/%s", dev->bus ? dev->bus->name : "no-bus", dev_name(dev)); if (chip->label) seq_printf(s, ", %s", chip->label); if (chip->can_sleep) seq_printf(s, ", can sleep"); seq_printf(s, ":\n"); if (chip->dbg_show_sleep) chip->dbg_show_sleep(s, NULL, chip, 0); } else { len += sprintf(gpio_sleep_buffer + len, "GPIOs %d-%d", chip->base, chip->base + chip->ngpio - 1); dev = chip->dev; if (dev) len += sprintf(gpio_sleep_buffer + len, ", %s/%s", dev->bus ? dev->bus->name : "no-bus", dev_name(dev)); if (chip->label) len += sprintf(gpio_sleep_buffer + len, ", %s", chip->label); if (chip->can_sleep) len += sprintf(gpio_sleep_buffer + len, ", can sleep"); if (chip->dbg_show_sleep) { ret = chip->dbg_show_sleep(NULL, gpio_sleep_buffer, chip, len); len = ret; } } }
/** * mmc_gpio_request_cd - request a gpio for card-detection * @host: mmc host * @gpio: gpio number requested * @debounce: debounce time in microseconds * * As devm_* managed functions are used in mmc_gpio_request_cd(), client * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up, * if the requesting and freeing are only needed at probing and unbinding time * for once. However, if client drivers do something special like runtime * switching for card-detection, they are responsible for calling * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own. * * If GPIO debouncing is desired, set the debounce parameter to a non-zero * value. The caller is responsible for ensuring that the GPIO driver associated * with the GPIO supports debouncing, otherwise an error will be returned. * * Returns zero on success, else an error. */ int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, unsigned int debounce) { struct mmc_gpio *ctx; int ret; ret = mmc_gpio_alloc(host); if (ret < 0) return ret; ctx = host->slot.handler_priv; ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, ctx->cd_label); if (ret < 0) /* * don't bother freeing memory. It might still get used by other * slot functions, in any case it will be freed, when the device * is destroyed. */ return ret; if (debounce) { ret = gpio_set_debounce(gpio, debounce); if (ret < 0) return ret; } ctx->override_cd_active_level = true; ctx->cd_gpio = gpio_to_desc(gpio); return 0; }
static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret = 0, i; clk_prepare_enable(skt->clk); if (skt->ops->hw_init) { ret = skt->ops->hw_init(skt); if (ret) return ret; } for (i = 0; i < ARRAY_SIZE(skt->stat); i++) { if (gpio_is_valid(skt->stat[i].gpio)) { unsigned long flags = GPIOF_IN; /* CD is active low by default */ if (i == SOC_STAT_CD) flags |= GPIOF_ACTIVE_LOW; ret = devm_gpio_request_one(skt->socket.dev.parent, skt->stat[i].gpio, flags, skt->stat[i].name); if (ret) { __soc_pcmcia_hw_shutdown(skt, i); return ret; } skt->stat[i].desc = gpio_to_desc(skt->stat[i].gpio); } if (i < SOC_STAT_VS1 && skt->stat[i].desc) { int irq = gpiod_to_irq(skt->stat[i].desc); if (irq > 0) { if (i == SOC_STAT_RDY) skt->socket.pci_irq = irq; else skt->stat[i].irq = irq; } } if (skt->stat[i].irq) { ret = request_irq(skt->stat[i].irq, soc_common_pcmcia_interrupt, IRQF_TRIGGER_NONE, skt->stat[i].name, skt); if (ret) { __soc_pcmcia_hw_shutdown(skt, i); return ret; } } } return ret; }
static struct gpio_desc *acpi_get_gpiod(char *path, int pin) { struct gpio_chip *chip; acpi_handle handle; acpi_status status; status = acpi_get_handle(NULL, path, &handle); if (ACPI_FAILURE(status)) return ERR_PTR(-ENODEV); chip = gpiochip_find(handle, acpi_gpiochip_find); if (!chip) return ERR_PTR(-ENODEV); if (pin < 0 || pin > chip->ngpio) return ERR_PTR(-EINVAL); return gpio_to_desc(chip->base + pin); }
static int panel_dpi_probe_pdata(struct platform_device *pdev) { const struct panel_dpi_platform_data *pdata; struct panel_drv_data *ddata = platform_get_drvdata(pdev); struct omap_dss_device *dssdev, *in; struct videomode vm; int r; pdata = dev_get_platdata(&pdev->dev); in = omap_dss_find_output(pdata->source); if (in == NULL) { dev_err(&pdev->dev, "failed to find video source '%s'\n", pdata->source); return -EPROBE_DEFER; } ddata->in = in; ddata->data_lines = pdata->data_lines; videomode_from_timing(pdata->display_timing, &vm); videomode_to_omap_video_timings(&vm, &ddata->videomode); dssdev = &ddata->dssdev; dssdev->name = pdata->name; r = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio, GPIOF_OUT_INIT_LOW, "panel enable"); if (r) goto err_gpio; ddata->enable_gpio = gpio_to_desc(pdata->enable_gpio); ddata->backlight_gpio = pdata->backlight_gpio; return 0; err_gpio: omap_dss_put_device(ddata->in); return r; }
/* Private function for resolving node pointer to gpio_chip */ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) { struct gg_data *gg_data = data; int ret; if ((gc->of_node != gg_data->gpiospec.np) || (gc->of_gpio_n_cells != gg_data->gpiospec.args_count) || (!gc->of_xlate)) return false; ret = gc->of_xlate(gc, &gg_data->gpiospec, gg_data->flags); if (ret < 0) { /* We've found the gpio chip, but the translation failed. * Return true to stop looking and return the translation * error via out_gpio */ gg_data->out_gpio = ERR_PTR(ret); return true; } gg_data->out_gpio = gpio_to_desc(ret + gc->base); return true; }
/** * mmc_gpio_request_ro - request a gpio for write-protection * @host: mmc host * @gpio: gpio number requested * * As devm_* managed functions are used in mmc_gpio_request_ro(), client * drivers do not need to explicitly call mmc_gpio_free_ro() for freeing up, * if the requesting and freeing are only needed at probing and unbinding time * for once. However, if client drivers do something special like runtime * switching for write-protection, they are responsible for calling * mmc_gpio_request_ro() and mmc_gpio_free_ro() as a pair on their own. * * Returns zero on success, else an error. */ int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) { struct mmc_gpio *ctx; int ret; if (!gpio_is_valid(gpio)) return -EINVAL; ret = mmc_gpio_alloc(host); if (ret < 0) return ret; ctx = host->slot.handler_priv; ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, ctx->ro_label); if (ret < 0) return ret; ctx->override_ro_active_level = true; ctx->ro_gpio = gpio_to_desc(gpio); return 0; }
static int init_port(void) { int i, nlow, nhigh, ret, irq; unsigned int base = gpio_calc_base(); /* Translate our GPIO number into absolute number */ gpio_out_pin = gpio_out_pin + base; gpio_in_pin = gpio_in_pin + base; if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) { printk(KERN_ALERT LIRC_DRIVER_NAME ": cant claim gpio pin %d\n", gpio_out_pin); ret = -ENODEV; goto exit_init_port; } if (gpio_request(gpio_in_pin, LIRC_DRIVER_NAME " ir/in")) { printk(KERN_ALERT LIRC_DRIVER_NAME ": cant claim gpio pin %d\n", gpio_in_pin); ret = -ENODEV; goto exit_gpio_free_out_pin; } gpio_direction_input(gpio_in_pin); gpio_direction_output(gpio_out_pin, 1); gpio_set_value(gpio_out_pin, invert); irq = gpio_to_irq(gpio_in_pin); dprintk("to_irq %d\n", irq); irqdata = irq_get_irq_data(irq); if (irqdata && irqdata->chip) { irqchip = irqdata->chip; } else { ret = -ENODEV; goto exit_gpio_free_in_pin; } /* if pin is high, then this must be an active low receiver. */ if (sense == -1) { /* * probe 9 times every 0.04s, collect "votes" for * active high/low */ nlow = 0; nhigh = 0; for (i = 0; i < 9; i++) { if (gpio_get_value(gpio_in_pin)) nlow++; else nhigh++; msleep(40); } sense = (nlow >= nhigh ? 1 : 0); printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active %s receiver on GPIO pin %d\n", sense ? "low" : "high", gpio_in_pin); } else { printk(KERN_INFO LIRC_DRIVER_NAME ": manually using active %s receiver on GPIO pin %d\n", sense ? "low" : "high", gpio_in_pin); } /* we have the gpio absolute number, translate into descriptor and * get the gpio chip it belongs to. In some devices there is more * than one gpio chip. "gco" can be equal to "gci" or not depending on * the device and the choosed GPIOs */ gco = gpiod_to_chip(gpio_to_desc(gpio_out_pin)); gci = gpiod_to_chip(gpio_to_desc(gpio_in_pin)); /* get the offset at the gpio chip * (we will use offsets for better performance) */ gpio_out_pin = gpio_out_pin - gco->base; gpio_in_pin = gpio_in_pin - gci->base; printk(KERN_INFO LIRC_DRIVER_NAME " IN: %s, base = %d, offset = %d\n", gci->label, gci->base, gpio_in_pin); printk(KERN_INFO LIRC_DRIVER_NAME " OUT: %s, base = %d, offset = %d\n", gco->label, gco->base, gpio_out_pin); return 0; exit_gpio_free_in_pin: gpio_free(gpio_in_pin); exit_gpio_free_out_pin: gpio_free(gpio_out_pin); exit_init_port: return ret; }
static int gpio_charger_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct gpio_charger_platform_data *pdata = dev->platform_data; struct power_supply_config psy_cfg = {}; struct gpio_charger *gpio_charger; struct power_supply_desc *charger_desc; unsigned long flags; int irq, ret; if (!pdata && !dev->of_node) { dev_err(dev, "No platform data\n"); return -ENOENT; } gpio_charger = devm_kzalloc(dev, sizeof(*gpio_charger), GFP_KERNEL); if (!gpio_charger) return -ENOMEM; /* * This will fetch a GPIO descriptor from device tree, ACPI or * boardfile descriptor tables. It's good to try this first. */ gpio_charger->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN); /* * If this fails and we're not using device tree, try the * legacy platform data method. */ if (IS_ERR(gpio_charger->gpiod) && !dev->of_node) { /* Non-DT: use legacy GPIO numbers */ if (!gpio_is_valid(pdata->gpio)) { dev_err(dev, "Invalid gpio pin in pdata\n"); return -EINVAL; } flags = GPIOF_IN; if (pdata->gpio_active_low) flags |= GPIOF_ACTIVE_LOW; ret = devm_gpio_request_one(dev, pdata->gpio, flags, dev_name(dev)); if (ret) { dev_err(dev, "Failed to request gpio pin: %d\n", ret); return ret; } /* Then convert this to gpiod for now */ gpio_charger->gpiod = gpio_to_desc(pdata->gpio); } else if (IS_ERR(gpio_charger->gpiod)) { /* Just try again if this happens */ if (PTR_ERR(gpio_charger->gpiod) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_err(dev, "error getting GPIO descriptor\n"); return PTR_ERR(gpio_charger->gpiod); } charger_desc = &gpio_charger->charger_desc; charger_desc->properties = gpio_charger_properties; charger_desc->num_properties = ARRAY_SIZE(gpio_charger_properties); charger_desc->get_property = gpio_charger_get_property; psy_cfg.of_node = dev->of_node; psy_cfg.drv_data = gpio_charger; if (pdata) { charger_desc->name = pdata->name; charger_desc->type = pdata->type; psy_cfg.supplied_to = pdata->supplied_to; psy_cfg.num_supplicants = pdata->num_supplicants; } else { charger_desc->name = dev->of_node->name; charger_desc->type = gpio_charger_get_type(dev); } if (!charger_desc->name) charger_desc->name = pdev->name; gpio_charger->charger = devm_power_supply_register(dev, charger_desc, &psy_cfg); if (IS_ERR(gpio_charger->charger)) { ret = PTR_ERR(gpio_charger->charger); dev_err(dev, "Failed to register power supply: %d\n", ret); return ret; } irq = gpiod_to_irq(gpio_charger->gpiod); if (irq > 0) { ret = devm_request_any_context_irq(dev, irq, gpio_charger_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, dev_name(dev), gpio_charger->charger); if (ret < 0) dev_warn(dev, "Failed to request irq: %d\n", ret); else gpio_charger->irq = irq; } platform_set_drvdata(pdev, gpio_charger); device_init_wakeup(dev, 1); return 0; }
static int pwm_backlight_probe(struct platform_device *pdev) { struct platform_pwm_backlight_data *data = dev_get_platdata(&pdev->dev); struct platform_pwm_backlight_data defdata; struct backlight_properties props; struct backlight_device *bl; struct device_node *node = pdev->dev.of_node; struct pwm_bl_data *pb; struct pwm_state state; unsigned int i; int ret; if (!data) { ret = pwm_backlight_parse_dt(&pdev->dev, &defdata); if (ret < 0) { dev_err(&pdev->dev, "failed to find platform data\n"); return ret; } data = &defdata; } if (data->init) { ret = data->init(&pdev->dev); if (ret < 0) return ret; } pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL); if (!pb) { ret = -ENOMEM; goto err_alloc; } pb->notify = data->notify; pb->notify_after = data->notify_after; pb->check_fb = data->check_fb; pb->exit = data->exit; pb->dev = &pdev->dev; pb->enabled = false; pb->post_pwm_on_delay = data->post_pwm_on_delay; pb->pwm_off_delay = data->pwm_off_delay; pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_ASIS); if (IS_ERR(pb->enable_gpio)) { ret = PTR_ERR(pb->enable_gpio); goto err_alloc; } /* * Compatibility fallback for drivers still using the integer GPIO * platform data. Must go away soon. */ if (!pb->enable_gpio && gpio_is_valid(data->enable_gpio)) { ret = devm_gpio_request_one(&pdev->dev, data->enable_gpio, GPIOF_OUT_INIT_HIGH, "enable"); if (ret < 0) { dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", data->enable_gpio, ret); goto err_alloc; } pb->enable_gpio = gpio_to_desc(data->enable_gpio); } /* * If the GPIO is not known to be already configured as output, that * is, if gpiod_get_direction returns either 1 or -EINVAL, change the * direction to output and set the GPIO as active. * Do not force the GPIO to active when it was already output as it * could cause backlight flickering or we would enable the backlight too * early. Leave the decision of the initial backlight state for later. */ if (pb->enable_gpio && gpiod_get_direction(pb->enable_gpio) != 0) gpiod_direction_output(pb->enable_gpio, 1); pb->power_supply = devm_regulator_get(&pdev->dev, "power"); if (IS_ERR(pb->power_supply)) { ret = PTR_ERR(pb->power_supply); goto err_alloc; } pb->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(pb->pwm) && PTR_ERR(pb->pwm) != -EPROBE_DEFER && !node) { dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); pb->legacy = true; pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); } if (IS_ERR(pb->pwm)) { ret = PTR_ERR(pb->pwm); if (ret != -EPROBE_DEFER) dev_err(&pdev->dev, "unable to request PWM\n"); goto err_alloc; } dev_dbg(&pdev->dev, "got pwm for backlight\n"); /* Sync up PWM state. */ pwm_init_state(pb->pwm, &state); /* * The DT case will set the pwm_period_ns field to 0 and store the * period, parsed from the DT, in the PWM device. For the non-DT case, * set the period from platform data if it has not already been set * via the PWM lookup table. */ if (!state.period && (data->pwm_period_ns > 0)) state.period = data->pwm_period_ns; ret = pwm_apply_state(pb->pwm, &state); if (ret) { dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n", ret); goto err_alloc; } if (data->levels) { /* * For the DT case, only when brightness levels is defined * data->levels is filled. For the non-DT case, data->levels * can come from platform data, however is not usual. */ for (i = 0; i <= data->max_brightness; i++) { if (data->levels[i] > pb->scale) pb->scale = data->levels[i]; pb->levels = data->levels; } } else if (!data->max_brightness) { /* * If no brightness levels are provided and max_brightness is * not set, use the default brightness table. For the DT case, * max_brightness is set to 0 when brightness levels is not * specified. For the non-DT case, max_brightness is usually * set to some value. */ /* Get the PWM period (in nanoseconds) */ pwm_get_state(pb->pwm, &state); ret = pwm_backlight_brightness_default(&pdev->dev, data, state.period); if (ret < 0) { dev_err(&pdev->dev, "failed to setup default brightness table\n"); goto err_alloc; } for (i = 0; i <= data->max_brightness; i++) { if (data->levels[i] > pb->scale) pb->scale = data->levels[i]; pb->levels = data->levels; } } else { /* * That only happens for the non-DT case, where platform data * sets the max_brightness value. */ pb->scale = data->max_brightness; } pb->lth_brightness = data->lth_brightness * (state.period / pb->scale); memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = data->max_brightness; bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, &pwm_backlight_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); if (pb->legacy) pwm_free(pb->pwm); goto err_alloc; } if (data->dft_brightness > data->max_brightness) { dev_warn(&pdev->dev, "invalid default brightness level: %u, using %u\n", data->dft_brightness, data->max_brightness); data->dft_brightness = data->max_brightness; } bl->props.brightness = data->dft_brightness; bl->props.power = pwm_backlight_initial_power_state(pb); backlight_update_status(bl); platform_set_drvdata(pdev, bl); return 0; err_alloc: if (data->exit) data->exit(&pdev->dev); return ret; }
int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, struct usb_phy_generic_platform_data *pdata) { enum usb_phy_type type = USB_PHY_TYPE_USB2; int err = 0; u32 clk_rate = 0; bool needs_vcc = false, needs_clk = false; if (dev->of_node) { struct device_node *node = dev->of_node; if (of_property_read_u32(node, "clock-frequency", &clk_rate)) clk_rate = 0; needs_vcc = of_property_read_bool(node, "vcc-supply"); needs_clk = of_property_read_bool(node, "clocks"); nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); err = PTR_ERR_OR_ZERO(nop->gpiod_reset); if (!err) { nop->gpiod_vbus = devm_gpiod_get_optional(dev, "vbus-detect", GPIOD_ASIS); err = PTR_ERR_OR_ZERO(nop->gpiod_vbus); } } else if (pdata) { type = pdata->type; clk_rate = pdata->clk_rate; needs_vcc = pdata->needs_vcc; if (gpio_is_valid(pdata->gpio_reset)) { err = devm_gpio_request_one(dev, pdata->gpio_reset, GPIOF_ACTIVE_LOW, dev_name(dev)); if (!err) nop->gpiod_reset = gpio_to_desc(pdata->gpio_reset); } nop->gpiod_vbus = pdata->gpiod_vbus; } if (err == -EPROBE_DEFER) return -EPROBE_DEFER; if (err) { dev_err(dev, "Error requesting RESET or VBUS GPIO\n"); return err; } if (nop->gpiod_reset) gpiod_direction_output(nop->gpiod_reset, 1); nop->phy.otg = devm_kzalloc(dev, sizeof(*nop->phy.otg), GFP_KERNEL); if (!nop->phy.otg) return -ENOMEM; nop->clk = devm_clk_get(dev, "main_clk"); if (IS_ERR(nop->clk)) { dev_dbg(dev, "Can't get phy clock: %ld\n", PTR_ERR(nop->clk)); if (needs_clk) return PTR_ERR(nop->clk); } if (!IS_ERR(nop->clk) && clk_rate) { err = clk_set_rate(nop->clk, clk_rate); if (err) { dev_err(dev, "Error setting clock rate\n"); return err; } } nop->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(nop->vcc)) { dev_dbg(dev, "Error getting vcc regulator: %ld\n", PTR_ERR(nop->vcc)); if (needs_vcc) return -EPROBE_DEFER; } nop->dev = dev; nop->phy.dev = nop->dev; nop->phy.label = "nop-xceiv"; nop->phy.set_suspend = nop_set_suspend; nop->phy.type = type; nop->phy.otg->state = OTG_STATE_UNDEFINED; nop->phy.otg->usb_phy = &nop->phy; nop->phy.otg->set_host = nop_set_host; nop->phy.otg->set_peripheral = nop_set_peripheral; return 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; }
static struct clk *clk_register_gpio(struct device *dev, const char *name, const char * const *parent_names, u8 num_parents, unsigned gpio, bool active_low, unsigned long flags, const struct clk_ops *clk_gpio_ops) { struct clk_gpio *clk_gpio; struct clk *clk; struct clk_init_data init = {}; unsigned long gpio_flags; int err; if (dev) clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL); else clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL); if (!clk_gpio) return ERR_PTR(-ENOMEM); if (active_low) gpio_flags = GPIOF_ACTIVE_LOW | GPIOF_OUT_INIT_HIGH; else gpio_flags = GPIOF_OUT_INIT_LOW; if (dev) err = devm_gpio_request_one(dev, gpio, gpio_flags, name); else err = gpio_request_one(gpio, gpio_flags, name); if (err) { if (err != -EPROBE_DEFER) pr_err("%s: %s: Error requesting clock control gpio %u\n", __func__, name, gpio); if (!dev) kfree(clk_gpio); return ERR_PTR(err); } init.name = name; init.ops = clk_gpio_ops; init.flags = flags | CLK_IS_BASIC; init.parent_names = parent_names; init.num_parents = num_parents; clk_gpio->gpiod = gpio_to_desc(gpio); clk_gpio->hw.init = &init; if (dev) clk = devm_clk_register(dev, &clk_gpio->hw); else clk = clk_register(NULL, &clk_gpio->hw); if (!IS_ERR(clk)) return clk; if (!dev) { gpiod_put(clk_gpio->gpiod); kfree(clk_gpio); } return clk; }
static int gpio_keys_setup_key(struct platform_device *pdev, struct input_dev *input, struct gpio_keys_drvdata *ddata, const struct gpio_keys_button *button, int idx, struct fwnode_handle *child) { const char *desc = button->desc ? button->desc : "gpio_keys"; struct device *dev = &pdev->dev; struct gpio_button_data *bdata = &ddata->data[idx]; irq_handler_t isr; unsigned long irqflags; int irq; int error; bdata->input = input; bdata->button = button; spin_lock_init(&bdata->lock); if (child) { bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, child, GPIOD_IN, desc); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error == -ENOENT) { /* * GPIO is optional, we may be dealing with * purely interrupt-driven setup. */ bdata->gpiod = NULL; } else { if (error != -EPROBE_DEFER) dev_err(dev, "failed to get gpio: %d\n", error); return error; } } } else if (gpio_is_valid(button->gpio)) { /* * Legacy GPIO number, so request the GPIO here and * convert it to descriptor. */ unsigned flags = GPIOF_IN; if (button->active_low) flags |= GPIOF_ACTIVE_LOW; error = devm_gpio_request_one(dev, button->gpio, flags, desc); if (error < 0) { dev_err(dev, "Failed to request GPIO %d, error %d\n", button->gpio, error); return error; } bdata->gpiod = gpio_to_desc(button->gpio); if (!bdata->gpiod) return -EINVAL; } if (bdata->gpiod) { if (button->debounce_interval) { error = gpiod_set_debounce(bdata->gpiod, button->debounce_interval * 1000); /* use timer if gpiolib doesn't provide debounce */ if (error < 0) bdata->software_debounce = button->debounce_interval; } if (button->irq) { bdata->irq = button->irq; } else { irq = gpiod_to_irq(bdata->gpiod); if (irq < 0) { error = irq; dev_err(dev, "Unable to get irq number for GPIO %d, error %d\n", button->gpio, error); return error; } bdata->irq = irq; } INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func); isr = gpio_keys_gpio_isr; irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; } else { if (!button->irq) { dev_err(dev, "Found button without gpio or irq\n"); return -EINVAL; } bdata->irq = button->irq; if (button->type && button->type != EV_KEY) { dev_err(dev, "Only EV_KEY allowed for IRQ buttons.\n"); return -EINVAL; } bdata->release_delay = button->debounce_interval; setup_timer(&bdata->release_timer, gpio_keys_irq_timer, (unsigned long)bdata); isr = gpio_keys_irq_isr; irqflags = 0; } bdata->code = &ddata->keymap[idx]; *bdata->code = button->code; input_set_capability(input, button->type ?: EV_KEY, *bdata->code); /* * Install custom action to cancel release timer and * workqueue item. */ error = devm_add_action(dev, gpio_keys_quiesce_key, bdata); if (error) { dev_err(dev, "failed to register quiesce action, error: %d\n", error); return error; } /* * If platform has specified that the button can be disabled, * we don't want it to share the interrupt line. */ if (!button->can_disable) irqflags |= IRQF_SHARED; error = devm_request_any_context_irq(dev, bdata->irq, isr, irqflags, desc, bdata); if (error < 0) { dev_err(dev, "Unable to claim irq %d; error %d\n", bdata->irq, error); return error; } return 0; }
static int xgold_mc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *codec_of_node = NULL; struct device_node *jack_of_node = NULL; struct snd_soc_dai_link *dai_link; struct xgold_mc_private *mc_drv_ctx; const char *codec_dai_name = NULL; int ret = 0; int i; xgold_debug("%s:\n", __func__); xgold_snd_card.dev = &pdev->dev; snd_soc_card_set_drvdata(&xgold_snd_card, &audio_native_mode); #ifdef CONFIG_OF codec_of_node = of_parse_phandle(np, "intel,audio-codec", 0); if (codec_of_node == NULL) { xgold_err("Unable to get codec node\n"); return -ENODEV; } ret = of_property_read_string(codec_of_node, PROP_CODEC_DAI_NAME, &codec_dai_name); if (ret) { xgold_err("Cannot get codec dai name ret %d\n", ret); return ret; } if (!audio_native_mode) { for (i = 0; i < xgold_snd_card.num_links; i++) { dai_link = &xgold_snd_card.dai_link[i]; if (!strncmp(dai_link->stream_name, "PCM Audio", strlen("PCM Audio"))) { dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,pcm-audio", 0); dai_link->codec_dai_name = "snd-soc-dummy-dai"; dai_link->codec_name = "snd-soc-dummy"; } else if (!strcmp(dai_link->stream_name, "Voice")) { /* FIXME: for Voice stream, platform is * snd-soc-dummy */ dai_link->cpu_of_node = of_parse_phandle(np, "intel,pcm-voice", 0); dai_link->codec_of_node = codec_of_node; dai_link->codec_dai_name = codec_dai_name; } else if (!strncmp(dai_link->stream_name, "XGOLD_SPEECH_PROBE_", strlen("XGOLD_SPEECH_PROBE_"))) { dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,speech", 0); dai_link->codec_dai_name = "snd-soc-dummy-dai"; dai_link->codec_name = "snd-soc-dummy"; } else if (!strncmp(dai_link->stream_name, "XGOLD_HW_PROBE_A", strlen("XGOLD_HW_PROBE_A"))) { dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,pcm-audio", 0); dai_link->codec_dai_name = "snd-soc-dummy-dai"; dai_link->codec_name = "snd-soc-dummy"; } else if (!strncmp(dai_link->stream_name, "XGOLD_HW_PROBE_B", strlen("XGOLD_HW_PROBE_B"))) { dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,pcm-audio", 0); dai_link->codec_dai_name = "snd-soc-dummy-dai"; dai_link->codec_name = "snd-soc-dummy"; } if (!dai_link->cpu_of_node) pr_err("error for %s DAI binding\n", dai_link->name); } } else { /* setup devices for native kernel support */ for (i = 0; i < xgold_snd_card.num_links; i++) { dai_link = &xgold_snd_card.dai_link[i]; dai_link->codec_of_node = codec_of_node; dai_link->codec_dai_name = codec_dai_name; if (!strncmp(dai_link->stream_name, "PCM Audio", strlen("PCM Audio"))) dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,pcm-audio", 0); else if (!strcmp(dai_link->stream_name, "Voice")) /* FIXME: for Voice stream, platform is * snd-soc-dummy */ dai_link->cpu_of_node = of_parse_phandle(np, "intel,pcm-voice", 0); else if (!strncmp(dai_link->stream_name, "XGOLD_SPEECH_PROBE_", strlen("XGOLD_SPEECH_PROBE_"))) dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,speech", 0); else if (!strncmp(dai_link->stream_name, "XGOLD_HW_PROBE_A", strlen("XGOLD_HW_PROBE_A"))) dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,pcm-audio", 0); else if (!strncmp(dai_link->stream_name, "XGOLD_HW_PROBE_B", strlen("XGOLD_HW_PROBE_B"))) dai_link->cpu_of_node = dai_link->platform_of_node = of_parse_phandle(np, "intel,pcm-audio", 0); if (!dai_link->cpu_of_node) pr_err("error for %s DAI binding\n", dai_link->name); } } #endif ret = snd_soc_register_card(&xgold_snd_card); if (ret < 0) { xgold_err("%s: unable to register sound card err %d\n", __func__, ret); return ret; } mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC); if (!mc_drv_ctx) { xgold_err("Allocation failed!\n"); return -ENOMEM; } platform_set_drvdata(pdev, mc_drv_ctx); /* spk gpio */ mc_drv_ctx->spk_pin = of_get_named_gpio_flags(np, PROP_SPK_AMP_NAME, 0, NULL); if (mc_drv_ctx->spk_pin <= 0) { xgold_debug("%s: unable to get speaker node %s\n", __func__, PROP_SPK_AMP_NAME); } else { xgold_debug("%s: Get speaker node %s value: %d !!!\n", __func__, PROP_SPK_AMP_NAME, mc_drv_ctx->spk_pin); ret = gpio_request(mc_drv_ctx->spk_pin, PROP_SPK_AMP_NAME); if (!ret) { xgold_debug("req gpio_request success!:%d\n", ret); gpiod_direction_output( gpio_to_desc(mc_drv_ctx->spk_pin), 0); } else { xgold_err("req gpio_request failed:%d\n", ret); } } jack_of_node = of_parse_phandle(np, "intel,jack", 0); if (!jack_of_node) return 0; mc_drv_ctx->jack = of_xgold_jack_probe(pdev, jack_of_node, &hs_jack); if (IS_ERR_OR_NULL(mc_drv_ctx->jack)) { xgold_err("Jack detection probe failed.\n"); mc_drv_ctx->jack = NULL; /* Allow machine probe to succeed anyway */ } mc_dev_ctx = mc_drv_ctx; return 0; }