示例#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
文件: bcma-hcd.c 项目: 020gzh/linux
static int bcma_hcd_probe(struct bcma_device *core)
{
	int err;
	struct bcma_hcd_device *usb_dev;

	/* TODO: Probably need checks here; is the core connected? */

	usb_dev = devm_kzalloc(&core->dev, sizeof(struct bcma_hcd_device),
			       GFP_KERNEL);
	if (!usb_dev)
		return -ENOMEM;
	usb_dev->core = core;

	if (core->dev.of_node)
		usb_dev->gpio_desc = devm_get_gpiod_from_child(&core->dev, "vcc",
							       &core->dev.of_node->fwnode);
	if (!IS_ERR_OR_NULL(usb_dev->gpio_desc))
		gpiod_direction_output(usb_dev->gpio_desc, 1);

	switch (core->id.id) {
	case BCMA_CORE_USB20_HOST:
	case BCMA_CORE_NS_USB20:
		err = bcma_hcd_usb20_init(usb_dev);
		if (err)
			return err;
		break;
	default:
		return -ENODEV;
	}

	bcma_set_drvdata(core, usb_dev);
	return 0;
}
示例#3
0
static int bcma_hcd_probe(struct bcma_device *dev)
{
	int err;
	u32 ohci_addr;
	struct bcma_hcd_device *usb_dev;
	struct bcma_chipinfo *chipinfo;

	chipinfo = &dev->bus->chipinfo;

	/* TODO: Probably need checks here; is the core connected? */

	if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))
		return -EOPNOTSUPP;

	usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device),
			       GFP_KERNEL);
	if (!usb_dev)
		return -ENOMEM;

	if (dev->dev.of_node)
		usb_dev->gpio_desc = devm_get_gpiod_from_child(&dev->dev, "vcc",
							       &dev->dev.of_node->fwnode);
	if (!IS_ERR_OR_NULL(usb_dev->gpio_desc))
		gpiod_direction_output(usb_dev->gpio_desc, 1);

	switch (dev->id.id) {
	case BCMA_CORE_NS_USB20:
		bcma_hcd_init_chip_arm(dev);
		break;
	case BCMA_CORE_USB20_HOST:
		bcma_hcd_init_chip_mips(dev);
		break;
	default:
		return -ENODEV;
	}

	/* In AI chips EHCI is addrspace 0, OHCI is 1 */
	ohci_addr = dev->addr_s[0];
	if ((chipinfo->id == BCMA_CHIP_ID_BCM5357 ||
	     chipinfo->id == BCMA_CHIP_ID_BCM4749)
	    && chipinfo->rev == 0)
		ohci_addr = 0x18009000;

	usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr);
	if (IS_ERR(usb_dev->ohci_dev))
		return PTR_ERR(usb_dev->ohci_dev);

	usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr);
	if (IS_ERR(usb_dev->ehci_dev)) {
		err = PTR_ERR(usb_dev->ehci_dev);
		goto err_unregister_ohci_dev;
	}

	bcma_set_drvdata(dev, usb_dev);
	return 0;

err_unregister_ohci_dev:
	platform_device_unregister(usb_dev->ohci_dev);
	return err;
}
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;
}
示例#5
0
static int nokia_modem_gpio_probe(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct nokia_modem_device *modem = dev_get_drvdata(dev);
	int gpio_count, gpio_name_count, i, err;

	gpio_count = of_gpio_count(np);

	if (gpio_count < 0) {
		dev_err(dev, "missing gpios: %d\n", gpio_count);
		return gpio_count;
	}

	gpio_name_count = of_property_count_strings(np, "gpio-names");

	if (gpio_count != gpio_name_count) {
		dev_err(dev, "number of gpios does not equal number of gpio names\n");
		return -EINVAL;
	}

	modem->gpios = devm_kzalloc(dev, gpio_count *
				sizeof(struct nokia_modem_gpio), GFP_KERNEL);
	if (!modem->gpios) {
		dev_err(dev, "Could not allocate memory for gpios\n");
		return -ENOMEM;
	}

	modem->gpio_amount = gpio_count;

	for (i = 0; i < gpio_count; i++) {
		modem->gpios[i].gpio = devm_gpiod_get_index(dev, NULL, i);
		if (IS_ERR(modem->gpios[i].gpio)) {
			dev_err(dev, "Could not get gpio %d\n", i);
			return PTR_ERR(modem->gpios[i].gpio);
		}

		err = of_property_read_string_index(np, "gpio-names", i,
						&(modem->gpios[i].name));
		if (err) {
			dev_err(dev, "Could not get gpio name %d\n", i);
			return err;
		}

		err = gpiod_direction_output(modem->gpios[i].gpio, 0);
		if (err)
			return err;

		err = gpiod_export(modem->gpios[i].gpio, 0);
		if (err)
			return err;

		err = gpiod_export_link(dev, modem->gpios[i].name,
							modem->gpios[i].gpio);
		if (err)
			return err;
	}

	return 0;
}
示例#6
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]);
	}
}
示例#7
0
static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
{
	struct bdw_rt5677_priv *bdw_rt5677 =
			snd_soc_card_get_drvdata(rtd->card);
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	/* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
	 * The ASRC clock source is clk_i2s1_asrc.
	 */
	rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER |
			RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
			RT5677_CLK_SEL_I2S1_ASRC);

	/* Request rt5677 GPIO for headphone amp control */
	bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev,
		"RT5677_GPIO_HP_AMP_SHDN_L", RT5677_GPIO_HP_AMP_SHDN_L, GPIOD_ASIS);
	if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
		dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
		return PTR_ERR(bdw_rt5677->gpio_hp_en);
	}
	gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0);

	/* Create and initialize headphone jack */
	if (!snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
			&headphone_jack)) {
		if (snd_soc_jack_add_pins(&headphone_jack, 1,
				&headphone_jack_pin))
			dev_err(codec->dev, "Can't add headphone jack pin\n");

		headphone_jack_gpio.gpiod_dev = codec->dev;
		if (snd_soc_jack_add_gpios(&headphone_jack, 1,
				&headphone_jack_gpio))
			dev_err(codec->dev, "Can't add headphone jack gpio\n");
	} else {
		dev_err(codec->dev, "Can't create headphone jack\n");
	}

	/* Create and initialize mic jack */
	if (!snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
			&mic_jack)) {
		if (snd_soc_jack_add_pins(&mic_jack, 1, &mic_jack_pin))
			dev_err(codec->dev, "Can't add mic jack pin\n");

		mic_jack_gpio.gpiod_dev = codec->dev;
		if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
			dev_err(codec->dev, "Can't add mic jack gpio\n");
	} else {
		dev_err(codec->dev, "Can't create mic jack\n");
	}
	bdw_rt5677->codec = codec;

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
	return 0;
}
示例#8
0
文件: panel-dpi.c 项目: 19Dan01/linux
static int panel_dpi_probe_of(struct platform_device *pdev)
{
	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
	struct device_node *node = pdev->dev.of_node;
	struct omap_dss_device *in;
	int r;
	struct display_timing timing;
	struct videomode vm;
	struct gpio_desc *gpio;

	gpio = devm_gpiod_get(&pdev->dev, "enable");

	if (IS_ERR(gpio)) {
		if (PTR_ERR(gpio) != -ENOENT)
			return PTR_ERR(gpio);
		else
			gpio = NULL;
	} else {
		gpiod_direction_output(gpio, 0);
	}

	ddata->enable_gpio = gpio;

	ddata->backlight_gpio = -ENOENT;

	r = of_get_display_timing(node, "panel-timing", &timing);
	if (r) {
		dev_err(&pdev->dev, "failed to get video timing\n");
		return r;
	}

	videomode_from_timing(&timing, &vm);
	videomode_to_omap_video_timings(&vm, &ddata->videomode);

	in = omapdss_of_find_source_for_first_ep(node);
	if (IS_ERR(in)) {
		dev_err(&pdev->dev, "failed to find video source\n");
		return PTR_ERR(in);
	}

	ddata->in = in;

	return 0;
}
示例#9
0
文件: at803x.c 项目: 3null/linux
static int at803x_probe(struct phy_device *phydev)
{
	struct device *dev = &phydev->dev;
	struct at803x_priv *priv;

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

	priv->gpiod_reset = devm_gpiod_get(dev, "reset");
	if (IS_ERR(priv->gpiod_reset))
		priv->gpiod_reset = NULL;
	else
		gpiod_direction_output(priv->gpiod_reset, 1);

	phydev->priv = priv;

	return 0;
}
示例#10
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);
}
示例#11
0
static void gpio_poweroff_do_poweroff(void)
{
	BUG_ON(!reset_gpio);

	/* drive it active, also inactive->active edge */
	gpiod_direction_output(reset_gpio, 1);
	mdelay(active_delay);

	/* drive inactive, also active->inactive edge */
	gpiod_set_value_cansleep(reset_gpio, 0);
	mdelay(inactive_delay);

	/* drive it active, also inactive->active edge */
	gpiod_set_value_cansleep(reset_gpio, 1);

	/* give it some time */
	mdelay(timeout);

	WARN_ON(1);
}
示例#12
0
文件: gpio-beeper.c 项目: 3null/linux
static int gpio_beeper_probe(struct platform_device *pdev)
{
	struct gpio_beeper *beep;
	struct input_dev *input;
	int err;

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

	beep->desc = devm_gpiod_get(&pdev->dev, NULL);
	if (IS_ERR(beep->desc))
		return PTR_ERR(beep->desc);

	input = devm_input_allocate_device(&pdev->dev);
	if (!input)
		return -ENOMEM;

	INIT_WORK(&beep->work, gpio_beeper_work);

	input->name		= pdev->name;
	input->id.bustype	= BUS_HOST;
	input->id.vendor	= 0x0001;
	input->id.product	= 0x0001;
	input->id.version	= 0x0100;
	input->close		= gpio_beeper_close;
	input->event		= gpio_beeper_event;

	input_set_capability(input, EV_SND, SND_BELL);

	err = gpiod_direction_output(beep->desc, 0);
	if (err)
		return err;

	input_set_drvdata(input, beep);

	return input_register_device(input);
}
示例#13
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;
}
示例#14
0
static int mt9m114_gpio_ctrl(struct v4l2_subdev *sd, int flag)
{
        struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct device *dev = &client->dev;
	int ret;

	if (!camera_reset) {
		camera_reset = gpiod_get_index(dev, "camera_0_reset", 0);
		if (IS_ERR(camera_reset)) {
			dev_err(dev,
				"%s: gpiod_get_index(camera_0_reset) failed\n",
				__func__);
			ret = PTR_ERR(camera_reset);
			goto err_camera_reset;
		}
	}

	ret = gpiod_direction_output(camera_reset, 1);
	if (ret) {
		pr_err("%s: failed to set gpio direction\n", __func__);
		gpiod_put(camera_reset);
		goto err_camera_reset;
	}

	if (!camera_power_down) {
		camera_power_down = gpiod_get_index(dev,
						    "camera_0_power_down", 1);
		if (IS_ERR(camera_power_down)) {
			pr_err("%s: gpiod_get_index(camera_power_down) failed\n",
			       __func__);
			ret = PTR_ERR(camera_power_down);
			goto err_power_down;
		}
	}

	ret = gpiod_direction_output(camera_power_down, 0);
	if (ret) {
		pr_err("%s: failed to set gpio direction\n", __func__);
		gpiod_put(camera_power_down);
		goto err_power_down;
	}

	if (flag) {
		gpiod_set_value(camera_reset, 0);
		gpiod_set_value(camera_power_down, 1);
		usleep_range(1000, 2000);
		gpiod_set_value(camera_reset, 1);
	} else {
		gpiod_set_value(camera_power_down, 0);
		gpiod_put(camera_power_down);

		gpiod_set_value(camera_reset, 0);
		gpiod_put(camera_reset);

		camera_reset = NULL;
		camera_power_down = NULL;
	}

	return 0;

err_camera_reset:
	camera_reset = NULL;
	return ret;

err_power_down:
	camera_power_down = NULL;
	return ret;
}
示例#15
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;
}
示例#16
0
static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct gsl_ts_data *ts;
	const struct firmware *fw = NULL;
	unsigned long irqflags;
	int error;
	bool acpipower;

	dev_warn(&client->dev, "%s: got a device named %s at address 0x%x, IRQ %d, flags 0x%x\n", __func__, client->name, client->addr, client->irq, client->flags);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "%s: i2c check functionality error\n", __func__);
		error = -ENXIO;
		goto release;
	}

	if (client->irq <= 0) {
		dev_err(&client->dev, "%s: missing IRQ configuration\n", __func__);
		error = -ENODEV;
		goto release;
	}
	
	ts = devm_kzalloc(&client->dev, sizeof(struct gsl_ts_data), GFP_KERNEL);
	if (!ts) {
		error = -ENOMEM;
		goto release;
	}
	
	ts->client = client;
	i2c_set_clientdata(client, ts);
	
	if (gsl_fw_name != NULL) {
		strncpy(ts->fw_name, gsl_fw_name, sizeof(ts->fw_name));
	} else {
		strncpy(ts->fw_name, GSL_FW_NAME_DEFAULT, sizeof(ts->fw_name));
	}
	error = request_firmware(&fw, ts->fw_name, &ts->client->dev);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to load firmware: %d\n", __func__, error);
		goto release;
	}

	error = gsl_ts_init(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to initialize: %d\n", __func__, error);
		goto release;
	}

	ts->input = devm_input_allocate_device(&client->dev);
	if (!ts->input) {
		dev_err(&client->dev, "%s: failed to allocate input device\n", __func__);
		error = -ENOMEM;
		goto release;
	}

	ts->input->name = "Silead GSLx680 Touchscreen";
	ts->input->id.bustype = BUS_I2C;
	ts->input->phys = "input/ts";

	input_set_capability(ts->input, EV_ABS, ABS_X);
	input_set_capability(ts->input, EV_ABS, ABS_Y);

	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, ts->jitter, ts->deadzone);
	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, ts->jitter, ts->deadzone);

	input_mt_init_slots(ts->input, ts->multi_touches, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);

	input_set_drvdata(ts->input, ts);

	error = input_register_device(ts->input);
	if (error) {
		dev_err(&client->dev, "%s: unable to register input device: %d\n", __func__, error);
		goto release;
	}

	/* Try to use ACPI power methods first */
	acpipower = false;
#ifdef CONFIG_ACPI
	if (ACPI_COMPANION(&client->dev)) {
		/* Wake the device up with a power on reset */
		if (acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3)) {
			dev_warn(&client->dev, "%s: failed to wake up device through ACPI: %d, using GPIO controls instead\n", __func__, error);
		} else {
			acpipower = true;
		}
	}
#endif
	/* Not available, use GPIO settings from DSDT/DT instead */
	if (!acpipower) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
		ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0);
#else
		ts->gpio = devm_gpiod_get_index(&client->dev, GSL_PWR_GPIO, 0, GPIOD_OUT_LOW);
#endif
		if (IS_ERR(ts->gpio)) {
			dev_err(&client->dev, "%s: error obtaining power pin GPIO resource\n", __func__);
			error = PTR_ERR(ts->gpio);
			goto release;
		}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
		error = gpiod_direction_output(ts->gpio, 0);
		if (error < 0) {
			dev_err(&client->dev, "%s: error setting GPIO pin direction\n", __func__);
			goto release;
		}
#endif
	} else {
		ts->gpio = NULL;
	}

	/* Enable power */
	gsl_ts_power(client, false);

	/* Execute the controller startup sequence */
	error = gsl_ts_reset_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip reset failed\n", __func__);
		goto release;
	}
	error = gsl_ts_write_fw(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: firmware transfer failed\n", __func__);
		goto release;
	}
	error = gsl_ts_startup_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip startup failed\n", __func__);
		goto release;
	}

	/*
	 * Systems using device tree should set up interrupt via DTS,
	 * the rest will use the default falling edge interrupts.
	 */
	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;

	/* Set up interrupt handler - do we still need to account for shared interrupts? */
	error = devm_request_threaded_irq(
		&client->dev,
		client->irq,
		NULL,
		gsl_ts_irq,
		irqflags | IRQF_ONESHOT,
		client->name,
		ts
	);
	if (error) {
		dev_err(&client->dev, "%s: failed to register interrupt\n", __func__);
		goto release;
	}

	/*
	 * Systems using device tree should set up wakeup via DTS,
	 * the rest will configure device as wakeup source by default.
	 */
	if (!client->dev.of_node) {
		device_init_wakeup(&client->dev, true);
	}

	ts->state = GSL_TS_GREEN;

release:
	if (fw) {
		release_firmware(fw);
	}

	if (error < 0) {
		return error;
	}
	return 0;
}
示例#17
0
文件: rx51.c 项目: Abioy/kasan
static int rx51_soc_probe(struct platform_device *pdev)
{
	struct rx51_audio_pdata *pdata;
	struct device_node *np = pdev->dev.of_node;
	struct snd_soc_card *card = &rx51_sound_card;
	int err;

	if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900"))
		return -ENODEV;

	card->dev = &pdev->dev;

	if (np) {
		struct device_node *dai_node;

		dai_node = of_parse_phandle(np, "nokia,cpu-dai", 0);
		if (!dai_node) {
			dev_err(&pdev->dev, "McBSP node is not provided\n");
			return -EINVAL;
		}
		rx51_dai[0].cpu_dai_name = NULL;
		rx51_dai[0].platform_name = NULL;
		rx51_dai[0].cpu_of_node = dai_node;
		rx51_dai[0].platform_of_node = dai_node;

		dai_node = of_parse_phandle(np, "nokia,audio-codec", 0);
		if (!dai_node) {
			dev_err(&pdev->dev, "Codec node is not provided\n");
			return -EINVAL;
		}
		rx51_dai[0].codec_name = NULL;
		rx51_dai[0].codec_of_node = dai_node;

		dai_node = of_parse_phandle(np, "nokia,audio-codec", 1);
		if (!dai_node) {
			dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n");
			return -EINVAL;
		}
		rx51_aux_dev[0].codec_name = NULL;
		rx51_aux_dev[0].codec_of_node = dai_node;
		rx51_codec_conf[0].dev_name = NULL;
		rx51_codec_conf[0].of_node = dai_node;

		dai_node = of_parse_phandle(np, "nokia,headphone-amplifier", 0);
		if (!dai_node) {
			dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
			return -EINVAL;
		}

		/* TODO: tpa6130a2a driver supports only a single instance, so
		 * this driver ignores the headphone-amplifier node for now.
		 * It's already mandatory in the DT binding to be future proof.
		 */
	}

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (pdata == NULL) {
		dev_err(card->dev, "failed to create private data\n");
		return -ENOMEM;
	}
	snd_soc_card_set_drvdata(card, pdata);

	pdata->tvout_selection_gpio = devm_gpiod_get(card->dev,
						     "tvout-selection");
	if (IS_ERR(pdata->tvout_selection_gpio)) {
		dev_err(card->dev, "could not get tvout selection gpio\n");
		return PTR_ERR(pdata->tvout_selection_gpio);
	}

	err = gpiod_direction_output(pdata->tvout_selection_gpio, 0);
	if (err) {
		dev_err(card->dev, "could not setup tvout selection gpio\n");
		return err;
	}

	pdata->jack_detection_gpio = devm_gpiod_get(card->dev,
						    "jack-detection");
	if (IS_ERR(pdata->jack_detection_gpio)) {
		dev_err(card->dev, "could not get jack detection gpio\n");
		return PTR_ERR(pdata->jack_detection_gpio);
	}

	pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch");
	if (IS_ERR(pdata->eci_sw_gpio)) {
		dev_err(card->dev, "could not get eci switch gpio\n");
		return PTR_ERR(pdata->eci_sw_gpio);
	}

	err = gpiod_direction_output(pdata->eci_sw_gpio, 1);
	if (err) {
		dev_err(card->dev, "could not setup eci switch gpio\n");
		return err;
	}

	pdata->speaker_amp_gpio = devm_gpiod_get(card->dev,
						 "speaker-amplifier");
	if (IS_ERR(pdata->speaker_amp_gpio)) {
		dev_err(card->dev, "could not get speaker enable gpio\n");
		return PTR_ERR(pdata->speaker_amp_gpio);
	}

	err = gpiod_direction_output(pdata->speaker_amp_gpio, 0);
	if (err) {
		dev_err(card->dev, "could not setup speaker enable gpio\n");
		return err;
	}

	err = devm_snd_soc_register_card(card->dev, card);
	if (err) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", err);
		return err;
	}

	return 0;
}
示例#18
0
文件: pwm_bl.c 项目: Anjali05/linux
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;
}
示例#19
0
static int sta32x_i2c_probe(struct i2c_client *i2c,
                            const struct i2c_device_id *id)
{
    struct device *dev = &i2c->dev;
    struct sta32x_priv *sta32x;
    int ret, i;

    sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv),
                          GFP_KERNEL);
    if (!sta32x)
        return -ENOMEM;

    mutex_init(&sta32x->coeff_lock);
    sta32x->pdata = dev_get_platdata(dev);

#ifdef CONFIG_OF
    if (dev->of_node) {
        ret = sta32x_probe_dt(dev, sta32x);
        if (ret < 0)
            return ret;
    }
#endif

    /* GPIOs */
    sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset");
    if (IS_ERR(sta32x->gpiod_nreset)) {
        ret = PTR_ERR(sta32x->gpiod_nreset);
        if (ret != -ENOENT && ret != -ENOSYS)
            return ret;

        sta32x->gpiod_nreset = NULL;
    } else {
        gpiod_direction_output(sta32x->gpiod_nreset, 0);
    }

    /* regulators */
    for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
        sta32x->supplies[i].supply = sta32x_supply_names[i];

    ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(sta32x->supplies),
                                  sta32x->supplies);
    if (ret != 0) {
        dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
        return ret;
    }

    sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap);
    if (IS_ERR(sta32x->regmap)) {
        ret = PTR_ERR(sta32x->regmap);
        dev_err(dev, "Failed to init regmap: %d\n", ret);
        return ret;
    }

    i2c_set_clientdata(i2c, sta32x);

    ret = snd_soc_register_codec(dev, &sta32x_codec, &sta32x_dai, 1);
    if (ret < 0)
        dev_err(dev, "Failed to register codec (%d)\n", ret);

    return ret;
}
示例#20
0
文件: cs35l32.c 项目: Abioy/kasan
static int cs35l32_i2c_probe(struct i2c_client *i2c_client,
				       const struct i2c_device_id *id)
{
	struct cs35l32_private *cs35l32;
	struct cs35l32_platform_data *pdata =
		dev_get_platdata(&i2c_client->dev);
	int ret, i;
	unsigned int devid = 0;
	unsigned int reg;


	cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private),
			       GFP_KERNEL);
	if (!cs35l32) {
		dev_err(&i2c_client->dev, "could not allocate codec\n");
		return -ENOMEM;
	}

	i2c_set_clientdata(i2c_client, cs35l32);

	cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap);
	if (IS_ERR(cs35l32->regmap)) {
		ret = PTR_ERR(cs35l32->regmap);
		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
		return ret;
	}

	if (pdata) {
		cs35l32->pdata = *pdata;
	} else {
		pdata = devm_kzalloc(&i2c_client->dev,
				     sizeof(struct cs35l32_platform_data),
				GFP_KERNEL);
		if (!pdata) {
			dev_err(&i2c_client->dev, "could not allocate pdata\n");
			return -ENOMEM;
		}
		if (i2c_client->dev.of_node) {
			ret = cs35l32_handle_of_data(i2c_client,
						     &cs35l32->pdata);
			if (ret != 0)
				return ret;
		}
	}

	for (i = 0; i < ARRAY_SIZE(cs35l32->supplies); i++)
		cs35l32->supplies[i].supply = cs35l32_supply_names[i];

	ret = devm_regulator_bulk_get(&i2c_client->dev,
				      ARRAY_SIZE(cs35l32->supplies),
				      cs35l32->supplies);
	if (ret != 0) {
		dev_err(&i2c_client->dev,
			"Failed to request supplies: %d\n", ret);
		return ret;
	}

	ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies),
				    cs35l32->supplies);
	if (ret != 0) {
		dev_err(&i2c_client->dev,
			"Failed to enable supplies: %d\n", ret);
		return ret;
	}

	/* Reset the Device */
	cs35l32->reset_gpio = devm_gpiod_get(&i2c_client->dev,
		"reset-gpios");
	if (IS_ERR(cs35l32->reset_gpio)) {
		ret = PTR_ERR(cs35l32->reset_gpio);
		if (ret != -ENOENT && ret != -ENOSYS)
			return ret;

		cs35l32->reset_gpio = NULL;
	} else {
		ret = gpiod_direction_output(cs35l32->reset_gpio, 0);
		if (ret)
			return ret;
		gpiod_set_value_cansleep(cs35l32->reset_gpio, 1);
	}

	/* initialize codec */
	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, &reg);
	devid = (reg & 0xFF) << 12;

	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, &reg);
	devid |= (reg & 0xFF) << 4;

	ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, &reg);
	devid |= (reg & 0xF0) >> 4;

	if (devid != CS35L32_CHIP_ID) {
		ret = -ENODEV;
		dev_err(&i2c_client->dev,
			"CS35L32 Device ID (%X). Expected %X\n",
			devid, CS35L32_CHIP_ID);
		return ret;
	}

	ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, &reg);
	if (ret < 0) {
		dev_err(&i2c_client->dev, "Get Revision ID failed\n");
		return ret;
	}

	ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch,
				    ARRAY_SIZE(cs35l32_monitor_patch));
	if (ret < 0) {
		dev_err(&i2c_client->dev, "Failed to apply errata patch\n");
		return ret;
	}

	dev_info(&i2c_client->dev,
		 "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF);

	/* Setup VBOOST Management */
	if (cs35l32->pdata.boost_mng)
		regmap_update_bits(cs35l32->regmap, CS35L32_AUDIO_LED_MNGR,
				   CS35L32_BOOST_MASK,
				cs35l32->pdata.boost_mng);

	/* Setup ADSP Format Config */
	if (cs35l32->pdata.sdout_share)
		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
				    CS35L32_ADSP_SHARE_MASK,
				cs35l32->pdata.sdout_share << 3);

	/* Setup ADSP Data Configuration */
	if (cs35l32->pdata.sdout_datacfg)
		regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL,
				   CS35L32_ADSP_DATACFG_MASK,
				cs35l32->pdata.sdout_datacfg << 4);

	/* Setup Low Battery Recovery  */
	if (cs35l32->pdata.batt_recov)
		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
				   CS35L32_BATT_REC_MASK,
				cs35l32->pdata.batt_recov << 1);

	/* Setup Low Battery Threshold */
	if (cs35l32->pdata.batt_thresh)
		regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD,
				   CS35L32_BATT_THRESH_MASK,
				cs35l32->pdata.batt_thresh << 4);

	/* Power down the AMP */
	regmap_update_bits(cs35l32->regmap, CS35L32_PWRCTL1, CS35L32_PDN_AMP,
			    CS35L32_PDN_AMP);

	/* Clear MCLK Error Bit since we don't have the clock yet */
	ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, &reg);

	ret =  snd_soc_register_codec(&i2c_client->dev,
			&soc_codec_dev_cs35l32, cs35l32_dai,
			ARRAY_SIZE(cs35l32_dai));
	if (ret < 0)
		goto err_disable;

	return 0;

err_disable:
	regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies),
			       cs35l32->supplies);
	return ret;
}
示例#21
0
static int axp288_extcon_probe(struct platform_device *pdev)
{
	struct axp288_extcon_info *info;
	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
	int ret, i, pirq, gpio;

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

	info->dev = &pdev->dev;
	info->regmap = axp20x->regmap;
	info->regmap_irqc = axp20x->regmap_irqc;
	info->pdata = pdev->dev.platform_data;

	if (!info->pdata) {
		/* Try ACPI provided pdata via device properties */
		if (!device_property_present(&pdev->dev,
					"axp288_extcon_data\n"))
			dev_err(&pdev->dev, "failed to get platform data\n");
		return -ENODEV;
	}
	platform_set_drvdata(pdev, info);

	axp288_extcon_log_rsi(info);

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
					      axp288_extcon_cables);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		return PTR_ERR(info->edev);
	}

	/* Register extcon device */
	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return ret;
	}

	/* Get otg transceiver phy */
	info->otg = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2);
	if (IS_ERR(info->otg)) {
		dev_err(&pdev->dev, "failed to get otg transceiver\n");
		return PTR_ERR(info->otg);
	}

	/* Set up gpio control for USB Mux */
	if (info->pdata->gpio_mux_cntl) {
		gpio = desc_to_gpio(info->pdata->gpio_mux_cntl);
		ret = devm_gpio_request(&pdev->dev, gpio, "USB_MUX");
		if (ret < 0) {
			dev_err(&pdev->dev,
				"failed to request the gpio=%d\n", gpio);
			return ret;
		}
		gpiod_direction_output(info->pdata->gpio_mux_cntl,
						EXTCON_GPIO_MUX_SEL_PMIC);
	}

	for (i = 0; i < EXTCON_IRQ_END; i++) {
		pirq = platform_get_irq(pdev, i);
		info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
		if (info->irq[i] < 0) {
			dev_err(&pdev->dev,
				"failed to get virtual interrupt=%d\n", pirq);
			ret = info->irq[i];
			return ret;
		}

		ret = devm_request_threaded_irq(&pdev->dev, info->irq[i],
				NULL, axp288_extcon_isr,
				IRQF_ONESHOT | IRQF_NO_SUSPEND,
				pdev->name, info);
		if (ret) {
			dev_err(&pdev->dev, "failed to request interrupt=%d\n",
							info->irq[i]);
			return ret;
		}
	}

	/* Enable interrupts */
	axp288_extcon_enable_irq(info);

	return 0;
}
示例#22
0
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;
}
示例#23
0
static int s6e8aa0_probe(struct mipi_dsi_device *dsi)
{
	struct device *dev = &dsi->dev;
	struct s6e8aa0 *ctx;
	int ret;

	ctx = devm_kzalloc(dev, sizeof(struct s6e8aa0), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	mipi_dsi_set_drvdata(dsi, ctx);

	ctx->dev = dev;

	dsi->lanes = 4;
	dsi->format = MIPI_DSI_FMT_RGB888;
	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST
		| MIPI_DSI_MODE_VIDEO_HFP | MIPI_DSI_MODE_VIDEO_HBP
		| MIPI_DSI_MODE_VIDEO_HSA | MIPI_DSI_MODE_EOT_PACKET
		| MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_AUTO_VERT;

	ret = s6e8aa0_parse_dt(ctx);
	if (ret < 0)
		return ret;

	ctx->supplies[0].supply = "vdd3";
	ctx->supplies[1].supply = "vci";
	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
				      ctx->supplies);
	if (ret < 0) {
		dev_err(dev, "failed to get regulators: %d\n", ret);
		return ret;
	}

	ctx->reset_gpio = devm_gpiod_get(dev, "reset");
	if (IS_ERR(ctx->reset_gpio)) {
		dev_err(dev, "cannot get reset-gpios %ld\n",
			PTR_ERR(ctx->reset_gpio));
		return PTR_ERR(ctx->reset_gpio);
	}
	ret = gpiod_direction_output(ctx->reset_gpio, 1);
	if (ret < 0) {
		dev_err(dev, "cannot configure reset-gpios %d\n", ret);
		return ret;
	}

	ctx->brightness = GAMMA_LEVEL_NUM - 1;

	drm_panel_init(&ctx->panel);
	ctx->panel.dev = dev;
	ctx->panel.funcs = &s6e8aa0_drm_funcs;

	ret = drm_panel_add(&ctx->panel);
	if (ret < 0)
		return ret;

	ret = mipi_dsi_attach(dsi);
	if (ret < 0)
		drm_panel_remove(&ctx->panel);

	return ret;
}
示例#24
0
static int lp8860_init(struct lp8860_led *led)
{
	unsigned int read_buf;
	int ret, i, reg_count;

	if (led->regulator) {
		ret = regulator_enable(led->regulator);
		if (ret) {
			dev_err(&led->client->dev,
				"Failed to enable regulator\n");
			return ret;
		}
	}

	if (led->enable_gpio)
		gpiod_direction_output(led->enable_gpio, 1);

	ret = lp8860_fault_check(led);
	if (ret)
		goto out;

	ret = regmap_read(led->regmap, LP8860_STATUS, &read_buf);
	if (ret)
		goto out;

	ret = lp8860_unlock_eeprom(led, LP8860_UNLOCK_EEPROM);
	if (ret) {
		dev_err(&led->client->dev, "Failed unlocking EEPROM\n");
		goto out;
	}

	reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]);
	for (i = 0; i < reg_count; i++) {
		ret = regmap_write(led->eeprom_regmap,
				lp8860_eeprom_disp_regs[i].reg,
				lp8860_eeprom_disp_regs[i].value);
		if (ret) {
			dev_err(&led->client->dev, "Failed writing EEPROM\n");
			goto out;
		}
	}

	ret = lp8860_unlock_eeprom(led, LP8860_LOCK_EEPROM);
	if (ret)
		goto out;

	ret = regmap_write(led->regmap,
			LP8860_EEPROM_CNTRL,
			LP8860_PROGRAM_EEPROM);
	if (ret) {
		dev_err(&led->client->dev, "Failed programming EEPROM\n");
		goto out;
	}

	return ret;

out:
	if (ret)
		if (led->enable_gpio)
			gpiod_direction_output(led->enable_gpio, 0);

	if (led->regulator) {
		ret = regulator_disable(led->regulator);
		if (ret)
			dev_err(&led->client->dev,
				"Failed to disable regulator\n");
	}

	return ret;
}
示例#25
0
static int rfkill_gpio_probe(struct platform_device *pdev)
{
	struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data;
	struct rfkill_gpio_data *rfkill;
	struct gpio_desc *gpio;
	int ret;

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

	if (ACPI_HANDLE(&pdev->dev)) {
		ret = rfkill_gpio_acpi_probe(&pdev->dev, rfkill);
		if (ret)
			return ret;
	} else if (pdata) {
		rfkill->name = pdata->name;
		rfkill->type = pdata->type;
	} else {
		return -ENODEV;
	}

	rfkill->clk = devm_clk_get(&pdev->dev, NULL);

	gpio = devm_gpiod_get(&pdev->dev, "reset");
	if (!IS_ERR(gpio)) {
		ret = gpiod_direction_output(gpio, 0);
		if (ret)
			return ret;
		rfkill->reset_gpio = gpio;
	}

	gpio = devm_gpiod_get(&pdev->dev, "shutdown");
	if (!IS_ERR(gpio)) {
		ret = gpiod_direction_output(gpio, 0);
		if (ret)
			return ret;
		rfkill->shutdown_gpio = gpio;
	}

	/* Make sure at-least one of the GPIO is defined and that
	 * a name is specified for this instance
	 */
	if ((!rfkill->reset_gpio && !rfkill->shutdown_gpio) || !rfkill->name) {
		dev_err(&pdev->dev, "invalid platform data\n");
		return -EINVAL;
	}

	rfkill->rfkill_dev = rfkill_alloc(rfkill->name, &pdev->dev,
					  rfkill->type, &rfkill_gpio_ops,
					  rfkill);
	if (!rfkill->rfkill_dev)
		return -ENOMEM;

	ret = rfkill_register(rfkill->rfkill_dev);
	if (ret < 0)
		return ret;

	platform_set_drvdata(pdev, rfkill);

	dev_info(&pdev->dev, "%s device registered.\n", rfkill->name);

	return 0;
}
示例#26
0
static int gsl_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct gsl_ts_data *ts;
	const struct firmware *fw;
	unsigned long irqflags;
	int error;

	dev_warn(&client->dev, "%s: got a device named %s at address 0x%x, IRQ %d, flags 0x%x\n", __func__, client->name, client->addr, client->irq, client->flags);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "%s: i2c check functionality error\n", __func__);
		return -ENXIO;
	}

	if (client->irq <= 0) {
		dev_err(&client->dev, "%s: missing IRQ configuration\n", __func__);
		return -ENODEV;
	}

	ts = devm_kzalloc(&client->dev, sizeof(struct gsl_ts_data), GFP_KERNEL);
	if (!ts) {
		return -ENOMEM;
	}

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

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
	/* Set up ACPI device descriptor GPIO name mappings.
		* This is a fallback, it will only be used if the system does not
		* provide a corresponding _DSD entry.
		*/
	error = acpi_dev_add_driver_gpios(ACPI_COMPANION(&client->dev), gsl_ts_acpi_gpios);
	if (error < 0) {
		dev_warn(&client->dev, "%s: failed to register GPIO names, continuing anyway\n", __func__);
	}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
	ts->gpio = devm_gpiod_get(&client->dev, GSL_PWR_GPIO);
#else
	ts->gpio = devm_gpiod_get(&client->dev, GSL_PWR_GPIO, GPIOD_OUT_LOW);
#endif
	if (IS_ERR(ts->gpio)) {
		dev_err(&client->dev, "%s: error obtaining power pin GPIO resource\n", __func__);
		error = PTR_ERR(ts->gpio);
		goto release_gpios;
	}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
	error = gpiod_direction_output(ts->gpio, 0);
	if (error < 0) {
		dev_err(&client->dev, "%s: error setting GPIO pin direction\n", __func__);
		goto release_gpios;
	}
#endif

	if (ACPI_COMPANION(&client->dev)) {
		/* Wake the device up with a power on reset */
		error = acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D3);
		if (error == 0) {
			error = acpi_bus_set_power(ACPI_HANDLE(&client->dev), ACPI_STATE_D0);
		}
		if (error) {
			dev_err(&client->dev, "%s: failed to wake up device through ACPI: %d, continuting anyway\n", __func__, error);
		}
	}

	error = request_firmware(&fw, GSL_FW_NAME, &ts->client->dev);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to load firmware: %d\n", __func__, error);
		goto release_gpios;
	}

	error = gsl_ts_init(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: failed to initialize: %d\n", __func__, error);
		goto release_fw;
	}

	ts->input = devm_input_allocate_device(&client->dev);
	if (!ts->input) {
		dev_err(&client->dev, "%s: failed to allocate input device\n", __func__);
		error = -ENOMEM;
		goto release_fw;
	}

	ts->input->name = "Silead GSLx680 Touchscreen";
	ts->input->id.bustype = BUS_I2C;
	ts->input->phys = "input/ts";

	input_set_capability(ts->input, EV_ABS, ABS_X);
	input_set_capability(ts->input, EV_ABS, ABS_Y);

	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, ts->x_max, ts->jitter, ts->deadzone);
	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, ts->jitter, ts->deadzone);

	input_mt_init_slots(ts->input, ts->multi_touches, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK);

	input_set_drvdata(ts->input, ts);

	error = input_register_device(ts->input);
	if (error) {
		dev_err(&client->dev, "%s: unable to register input device: %d\n", __func__, error);
		goto release_fw;
	}

	/*
	 * Systems using device tree should set up interrupt via DTS,
	 * the rest will use the default falling edge interrupts.
	 */
	irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;

	/* Set up interrupt handler - do we still need to account for shared interrupts? */
	error = devm_request_threaded_irq(
		&client->dev,
		client->irq,
		NULL,
		gsl_ts_irq,
		irqflags | IRQF_ONESHOT,
		client->name,
		ts
	);
	if (error) {
		dev_err(&client->dev, "%s: failed to register interrupt\n", __func__);
		goto release_fw;
	}

	/* Execute the controller startup sequence */
	error = gsl_ts_reset_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip reset failed\n", __func__);
		goto release_fw;
	}
	error = gsl_ts_write_fw(ts, fw);
	if (error < 0) {
		dev_err(&client->dev, "%s: firmware transfer failed\n", __func__);
		goto release_fw;
	}
	error = gsl_ts_startup_chip(client);
	if (error < 0) {
		dev_err(&client->dev, "%s: chip startup failed\n", __func__);
		goto release_fw;
	}

	/*
	 * Systems using device tree should set up wakeup via DTS,
	 * the rest will configure device as wakeup source by default.
	 */
	if (!client->dev.of_node) {
		device_init_wakeup(&client->dev, true);
	}

	ts->state = GSL_TS_GREEN;

release_fw:
	if (fw) {
		release_firmware(fw);
	}

release_gpios:
	if (error < 0) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
		acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev));
#endif

		return error;
	}
	return 0;
}
示例#27
0
int adau1977_probe(struct device *dev, struct regmap *regmap,
	enum adau1977_type type, void (*switch_mode)(struct device *dev))
{
	unsigned int power_off_mask;
	struct adau1977 *adau1977;
	int ret;

	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL);
	if (adau1977 == NULL)
		return -ENOMEM;

	adau1977->dev = dev;
	adau1977->type = type;
	adau1977->regmap = regmap;
	adau1977->switch_mode = switch_mode;
	adau1977->max_master_fs = 192000;

	adau1977->constraints.list = adau1977_rates;
	adau1977->constraints.count = ARRAY_SIZE(adau1977_rates);

	adau1977->avdd_reg = devm_regulator_get(dev, "AVDD");
	if (IS_ERR(adau1977->avdd_reg))
		return PTR_ERR(adau1977->avdd_reg);

	adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD");
	if (IS_ERR(adau1977->dvdd_reg)) {
		if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV)
			return PTR_ERR(adau1977->dvdd_reg);
		adau1977->dvdd_reg = NULL;
	}

	adau1977->reset_gpio = devm_gpiod_get(dev, "reset");
	if (IS_ERR(adau1977->reset_gpio)) {
		ret = PTR_ERR(adau1977->reset_gpio);
		if (ret != -ENOENT && ret != -ENOSYS)
			return PTR_ERR(adau1977->reset_gpio);
		adau1977->reset_gpio = NULL;
	}

	dev_set_drvdata(dev, adau1977);

	if (adau1977->reset_gpio) {
		ret = gpiod_direction_output(adau1977->reset_gpio, 0);
		if (ret)
			return ret;
		ndelay(100);
	}

	ret = adau1977_power_enable(adau1977);
	if (ret)
		return ret;

	if (type == ADAU1977) {
		ret = adau1977_setup_micbias(adau1977);
		if (ret)
			goto err_poweroff;
	}

	if (adau1977->dvdd_reg)
		power_off_mask = ~0;
	else
		power_off_mask = (unsigned int)~ADAU1977_BLOCK_POWER_SAI_LDO_EN;

	ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
				power_off_mask, 0x00);
	if (ret)
		goto err_poweroff;

	ret = adau1977_power_disable(adau1977);
	if (ret)
		return ret;

	return snd_soc_register_codec(dev, &adau1977_codec_driver,
			&adau1977_dai, 1);

err_poweroff:
	adau1977_power_disable(adau1977);
	return ret;

}
示例#28
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;
}