示例#1
0
static int led_pwm_probe(struct platform_device *pdev)
{
    struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev);
    struct led_pwm_priv *priv;
    int i, ret = 0;

    if (pdata && pdata->num_leds) {
        priv = devm_kzalloc(&pdev->dev,
                            sizeof_pwm_leds_priv(pdata->num_leds),
                            GFP_KERNEL);
        if (!priv)
            return -ENOMEM;

        for (i = 0; i < pdata->num_leds; i++) {
            struct led_pwm *cur_led = &pdata->leds[i];
            struct led_pwm_data *led_dat = &priv->leds[i];

            led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
            if (IS_ERR(led_dat->pwm)) {
                ret = PTR_ERR(led_dat->pwm);
                dev_err(&pdev->dev,
                        "unable to request PWM for %s\n",
                        cur_led->name);
                goto err;
            }

            led_dat->cdev.name = cur_led->name;
            led_dat->cdev.default_trigger = cur_led->default_trigger;
            led_dat->active_low = cur_led->active_low;
            led_dat->period = cur_led->pwm_period_ns;
            led_dat->cdev.brightness_set = led_pwm_set;
            led_dat->cdev.brightness = LED_OFF;
            led_dat->cdev.max_brightness = cur_led->max_brightness;
            led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;

            led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
            if (led_dat->can_sleep)
                INIT_WORK(&led_dat->work, led_pwm_work);

            ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
            if (ret < 0)
                goto err;
        }
        priv->num_leds = pdata->num_leds;
    } else {
        priv = led_pwm_create_of(pdev);
        if (!priv)
            return -ENODEV;
    }

    platform_set_drvdata(pdev, priv);

    return 0;

err:
    while (i--)
        led_classdev_unregister(&priv->leds[i].cdev);

    return ret;
}
示例#2
0
static int pwm_regulator_probe(struct platform_device *pdev)
{
	const struct regulator_init_data *init_data;
	struct pwm_regulator_data *drvdata;
	struct regulator_dev *regulator;
	struct regulator_config config = { };
	struct device_node *np = pdev->dev.of_node;
	int ret;

	if (!np) {
		dev_err(&pdev->dev, "Device Tree node missing\n");
		return -EINVAL;
	}

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

	if (of_find_property(np, "voltage-table", NULL))
		ret = pwm_regulator_init_table(pdev, drvdata);
	else
		ret = pwm_regulator_init_continuous(pdev, drvdata);
	if (ret)
		return ret;

	init_data = of_get_regulator_init_data(&pdev->dev, np,
					       &pwm_regulator_desc);
	if (!init_data)
		return -ENOMEM;

	config.of_node = np;
	config.dev = &pdev->dev;
	config.driver_data = drvdata;
	config.init_data = init_data;

	drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(drvdata->pwm)) {
		dev_err(&pdev->dev, "Failed to get PWM\n");
		return PTR_ERR(drvdata->pwm);
	}

	regulator = devm_regulator_register(&pdev->dev,
					    &pwm_regulator_desc, &config);
	if (IS_ERR(regulator)) {
		dev_err(&pdev->dev, "Failed to register regulator %s\n",
			pwm_regulator_desc.name);
		return PTR_ERR(regulator);
	}

	return 0;
}
static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
{
	unsigned int period = lp->pdata->period_ns;
	unsigned int duty = br * period / max_br;
	struct pwm_device *pwm;

	/* request pwm device with the consumer name */
	if (!lp->pwm) {
		pwm = devm_pwm_get(lp->dev, lp->chipid->name);
		if (IS_ERR(pwm))
			return;

		lp->pwm = pwm;
	}

	pwm_config(lp->pwm, duty, period);
	if (duty)
		pwm_enable(lp->pwm);
	else
		pwm_disable(lp->pwm);
}
示例#4
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 pwm_bl_data *pb;
	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;
	}

	if (data->levels) {
		unsigned int i;

		for (i = 0; i <= data->max_brightness; i++)
			if (data->levels[i] > pb->scale)
				pb->scale = data->levels[i];

		pb->levels = data->levels;
	} else
		pb->scale = data->max_brightness;

	pb->enable_gpio = data->enable_gpio;
	pb->enable_gpio_flags = data->enable_gpio_flags;
	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;

	if (gpio_is_valid(pb->enable_gpio)) {
		unsigned long flags;

		if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
			flags = GPIOF_OUT_INIT_HIGH;
		else
			flags = GPIOF_OUT_INIT_LOW;

		ret = gpio_request_one(pb->enable_gpio, flags, "enable");
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n",
				pb->enable_gpio, ret);
			goto err_alloc;
		}
	}

	pb->power_supply = devm_regulator_get(&pdev->dev, "power");
	if (IS_ERR(pb->power_supply)) {
		ret = PTR_ERR(pb->power_supply);
		goto err_gpio;
	}

	pb->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(pb->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");

		pb->pwm = pwm_request(data->pwm_id, "pwm-backlight");
		if (IS_ERR(pb->pwm)) {
			dev_err(&pdev->dev, "unable to request legacy PWM\n");
			ret = PTR_ERR(pb->pwm);
			goto err_gpio;
		}
	}

	dev_dbg(&pdev->dev, "got pwm for backlight\n");

	/*
	 * 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 (data->pwm_period_ns > 0)
		pwm_set_period(pb->pwm, data->pwm_period_ns);

	pb->period = pwm_get_period(pb->pwm);
	pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = data->max_brightness;
	bl = backlight_device_register("lcd-bl", &pdev->dev, pb,
				       &pwm_backlight_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		ret = PTR_ERR(bl);
		goto err_gpio;
	}

	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;
	backlight_update_status(bl);

	platform_set_drvdata(pdev, bl);
	return 0;

err_gpio:
	if (gpio_is_valid(pb->enable_gpio))
		gpio_free(pb->enable_gpio);
err_alloc:
	if (data->exit)
		data->exit(&pdev->dev);
	return ret;
}
示例#5
0
文件: lm3630a_bl.c 项目: 020gzh/linux
static int lm3630a_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct lm3630a_platform_data *pdata = dev_get_platdata(&client->dev);
	struct lm3630a_chip *pchip;
	int rval;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "fail : i2c functionality check\n");
		return -EOPNOTSUPP;
	}

	pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630a_chip),
			     GFP_KERNEL);
	if (!pchip)
		return -ENOMEM;
	pchip->dev = &client->dev;

	pchip->regmap = devm_regmap_init_i2c(client, &lm3630a_regmap);
	if (IS_ERR(pchip->regmap)) {
		rval = PTR_ERR(pchip->regmap);
		dev_err(&client->dev, "fail : allocate reg. map: %d\n", rval);
		return rval;
	}

	i2c_set_clientdata(client, pchip);
	if (pdata == NULL) {
		pdata = devm_kzalloc(pchip->dev,
				     sizeof(struct lm3630a_platform_data),
				     GFP_KERNEL);
		if (pdata == NULL)
			return -ENOMEM;
		/* default values */
		pdata->leda_ctrl = LM3630A_LEDA_ENABLE;
		pdata->ledb_ctrl = LM3630A_LEDB_ENABLE;
		pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS;
		pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS;
		pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS;
		pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS;
	}
	pchip->pdata = pdata;

	/* chip initialize */
	rval = lm3630a_chip_init(pchip);
	if (rval < 0) {
		dev_err(&client->dev, "fail : init chip\n");
		return rval;
	}
	/* backlight register */
	rval = lm3630a_backlight_register(pchip);
	if (rval < 0) {
		dev_err(&client->dev, "fail : backlight register.\n");
		return rval;
	}
	/* pwm */
	if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) {
		pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm");
		if (IS_ERR(pchip->pwmd)) {
			dev_err(&client->dev, "fail : get pwm device\n");
			return PTR_ERR(pchip->pwmd);
		}
	}
	pchip->pwmd->period = pdata->pwm_period;

	/* interrupt enable  : irq 0 is not allowed */
	pchip->irq = client->irq;
	if (pchip->irq) {
		rval = lm3630a_intr_config(pchip);
		if (rval < 0)
			return rval;
	}
	dev_info(&client->dev, "LM3630A backlight register OK.\n");
	return 0;
}
static int pwm_test_probe(struct platform_device *pdev)
{
	struct pwm_test *pwm_test;
	struct pinctrl *pinctrl;
	struct device_node *node = (&pdev->dev)->of_node;
	int rc;

	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(pinctrl))
		dev_warn(&pdev->dev, "unable to select pin group. PWM not muxed right\n");


	pwm_test = devm_kzalloc(&pdev->dev, sizeof(*pwm_test), GFP_KERNEL);

	if (!pwm_test) {
		dev_err(&pdev->dev, "memory error\n");
		return -ENOMEM;
	}

	if (pwm_test_class_init(&pdev->dev)) {
		dev_err(&pdev->dev, "sysfs creation failed\n");
		return -EINVAL;
	}

	pwm_test->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(pwm_test->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM\n");	
		return -EINVAL;			
	}

	pwm_test->requested = 1;

	pr_debug("pwm_test got PWM\n");

	/* Get the properties of the pwm. This is set in the device driver (tiehrpwm) */
	pwm_test->period = pwm_get_period(pwm_test->pwm);

	/* Determine running or not from the device tree */
	rc = of_property_read_u32(node, "enabled", (u32*) &(pwm_test->run));
	if (rc < 0)
		return rc;

	if(pwm_test->run){
		rc = pwm_enable(pwm_test->pwm);
		if (rc < 0)
				return rc;
	}

	/* Determine the duty from the device tree */
	rc = of_property_read_u32(node, "duty", (u32*) &(pwm_test->duty_s));
	if (rc < 0)
		return rc;

	rc = pwm_config(pwm_test->pwm, pwm_test->duty_s, pwm_test->period);
	if (rc) {
		pr_err("Unable to set pwm duty %d\n", rc);
		return rc;
	}
	

	platform_set_drvdata(pdev, pwm_test);
	return 0;
}
示例#7
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;
}
示例#8
0
static int pwm_regulator_probe(struct platform_device *pdev)
{
	struct pwm_regulator_data *drvdata;
	struct property *prop;
	struct regulator_dev *regulator;
	struct regulator_config config = { };
	struct device_node *np = pdev->dev.of_node;
	int length, ret;

	if (!np) {
		dev_err(&pdev->dev, "Device Tree node missing\n");
		return -EINVAL;
	}

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

	memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(pwm_regulator_desc));

	/* determine the number of voltage-table */
	prop = of_find_property(np, "voltage-table", &length);
	if (!prop) {
		dev_err(&pdev->dev, "No voltage-table\n");
		return -EINVAL;
	}

	if ((length < sizeof(*drvdata->duty_cycle_table)) ||
	    (length % sizeof(*drvdata->duty_cycle_table))) {
		dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
			length);
		return -EINVAL;
	}

	drvdata->desc.n_voltages = length / sizeof(*drvdata->duty_cycle_table);

	drvdata->duty_cycle_table = devm_kzalloc(&pdev->dev,
						 length, GFP_KERNEL);
	if (!drvdata->duty_cycle_table)
		return -ENOMEM;

	/* read voltage table from DT property */
	ret = of_property_read_u32_array(np, "voltage-table",
					 (u32 *)drvdata->duty_cycle_table,
					 length / sizeof(u32));
	if (ret < 0) {
		dev_err(&pdev->dev, "read voltage-table failed\n");
		return ret;
	}

	config.init_data = of_get_regulator_init_data(&pdev->dev, np,
						      &drvdata->desc);
	if (!config.init_data)
		return -ENOMEM;

	config.of_node = np;
	config.dev = &pdev->dev;
	config.driver_data = drvdata;

	drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(drvdata->pwm)) {
		dev_err(&pdev->dev, "Failed to get PWM\n");
		return PTR_ERR(drvdata->pwm);
	}

	regulator = devm_regulator_register(&pdev->dev,
					    &drvdata->desc, &config);
	if (IS_ERR(regulator)) {
		dev_err(&pdev->dev, "Failed to register regulator %s\n",
			drvdata->desc.name);
		return PTR_ERR(regulator);
	}

	return 0;
}
static int pwm_test_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct pwm_test *pwm_test;
	struct of_phandle_args args;
	struct pinctrl *pinctrl;
	u32 val;
	int rc;

	if (node == NULL) {
		dev_err(dev, "Non DT platforms not supported\n");
		return -EINVAL;
	}

	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(pinctrl))
		dev_warn(&pdev->dev, "Unable to select pin group\n");

	pwm_test = devm_kzalloc(&pdev->dev, sizeof(*pwm_test), GFP_KERNEL);
	if (!pwm_test) {
		dev_err(&pdev->dev, "memory error\n");
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, pwm_test);

	/* now do the probe time config */
	pwm_test->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(pwm_test->pwm)) {
		dev_err(dev, "unable to request PWM\n");
		return PTR_ERR(pwm_test->pwm);
	}

	rc = of_parse_phandle_with_args(node, "pwms", "#pwm-cells", 0, &args);
	if (rc != 0) {
		dev_err(dev, "of_parse_phandle_with_args() failed\n");
		return rc;
	}

	/* read the period */
	pwm_test->period = args.args[1];

	/* should be at least 2, but 3 is possible to store polarity */
	pwm_test->polarity = PWM_POLARITY_NORMAL;
	/* PWM_SPEC_POLARITY is (1 << 0) */
	if (args.args_count >= 3 && (args.args[2] & (1 << 0)) != 0)
		pwm_test->polarity = PWM_POLARITY_INVERSED;

	/* Determine the duty from the device tree */
	rc = of_property_read_u32(node, "duty", &val);
	if (rc != 0)
		val = 0;	/* default is 0 */
	pwm_test->duty = val;

	/* polarity is already set */
	rc = pwm_config(pwm_test->pwm, pwm_test->duty, pwm_test->period);
	if (rc) {
		dev_err(dev, "pwm_config() failed\n");
		return rc;
	}

	/* Determine running or not from the device tree */
	rc = of_property_read_u32(node, "enabled", &val);
	if (rc < 0)
		val = 0;	/* default is disabled */

	/* single bit */
	pwm_test->run = !!val;

	if (pwm_test->run) {
		rc = pwm_enable(pwm_test->pwm);
		if (rc < 0) {
			dev_err(dev, "pwm_enable failed\n");
			return rc;
		}
	}

	rc = sysfs_create_group(&dev->kobj, &pwm_device_attr_group);
	if (rc != 0) {
		dev_err(dev, "Unable to create sysfs entries\n");
		return rc;
	}

	return 0;
}
示例#10
0
static int pwm_backlight_probe(struct platform_device *pdev)
{
	struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
	struct platform_pwm_backlight_data defdata;
	struct backlight_properties props;
	struct backlight_device *bl;
	struct pwm_bl_data *pb;
	unsigned int max;
	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) {
		dev_err(&pdev->dev, "no memory for state\n");
		ret = -ENOMEM;
		goto err_alloc;
	}

	if (data->levels) {
		max = data->levels[data->max_brightness];
		pb->levels = data->levels;
	} else
		max = data->max_brightness;

	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->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(pb->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");

		pb->pwm = pwm_request(data->pwm_id, "pwm-backlight");
		if (IS_ERR(pb->pwm)) {
			dev_err(&pdev->dev, "unable to request legacy PWM\n");
			ret = PTR_ERR(pb->pwm);
			goto err_alloc;
		}
	}

	dev_dbg(&pdev->dev, "got pwm for backlight\n");

	/*
	 * 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 (data->pwm_period_ns > 0)
		pwm_set_period(pb->pwm, data->pwm_period_ns);

	pb->period = pwm_get_period(pb->pwm);
	pb->lth_brightness = data->lth_brightness * (pb->period / max);

	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);
		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;
	backlight_update_status(bl);

	platform_set_drvdata(pdev, bl);
	return 0;

err_alloc:
	if (data->exit)
		data->exit(&pdev->dev);
	return ret;
}
static int __init pwm_regulator_probe(struct platform_device *pdev)
{
	struct pwm_platform_data *pdata = pdev->dev.platform_data;
	struct pwm_regulator_board *pwm_pdev;
	struct of_regulator_match *pwm_reg_matches = NULL;
	struct regulator_init_data *reg_data;
	struct regulator_config config = { };
	const char *rail_name = NULL;
	struct regulator_dev *pwm_rdev;
	int ret, i = 0;
	struct regulator *dc;

	pwm_pdev = devm_kzalloc(&pdev->dev, sizeof(*pwm_pdev),
					GFP_KERNEL);
	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata),
					GFP_KERNEL);

	if (pdev->dev.of_node)
		pwm_pdev = pwm_regulator_parse_dt(pdev, &pwm_reg_matches);

	if (!pwm_pdev) {
		dev_err(&pdev->dev, "Platform data not found\n");
		return -EINVAL;
	}

	if (!pwm_pdev->pwm_init_vol)
		pdata->pwm_voltage = 1100000;	/* default 1.1v*/
	else
		pdata->pwm_voltage = pwm_pdev->pwm_init_vol;

	if (!pwm_pdev->pwm_max_vol)
		pdata->max_uV = 1400000;
	else
		pdata->max_uV = pwm_pdev->pwm_max_vol;

	if (!pwm_pdev->pwm_min_vol)
		pdata->min_uV = 1000000;
	else
		pdata->min_uV = pwm_pdev->pwm_min_vol;

	if (pwm_pdev->pwm_suspend_vol < pwm_pdev->pwm_min_vol)
		pdata->suspend_voltage = pwm_pdev->pwm_min_vol;
	else if (pwm_pdev->pwm_suspend_vol > pwm_pdev->pwm_max_vol)
		pdata->suspend_voltage = pwm_pdev->pwm_max_vol;
	else
		pdata->suspend_voltage = pwm_pdev->pwm_suspend_vol;

	pdata->pwm_voltage_map = pwm_pdev->pwm_voltage_map;
	pdata->pwm_id = pwm_pdev->pwm_id;
	pdata->coefficient = pwm_pdev->pwm_coefficient;
	pdata->pwm_vol_map_count = pwm_pdev->pwm_vol_map_count;

	pdata->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(pdata->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");

		pdata->pwm = pwm_request(pdata->pwm_id, "pwm-regulator");
		if (IS_ERR(pdata->pwm)) {
			dev_err(&pdev->dev, "unable to request legacy PWM\n");
			ret = PTR_ERR(pdata->pwm);
			goto err;
		}
	}
	if (pdata->pwm_period_ns > 0)
		pwm_set_period(pdata->pwm, pdata->pwm_period_ns);

	pdata->period = pwm_get_period(pdata->pwm);

	mutex_init(&pdata->mutex_pwm);

	if (pwm_pdev) {
		pdata->num_regulators = pwm_pdev->num_regulators;
		pdata->rdev = kcalloc(pdata->num_regulators, sizeof(struct regulator_dev *), GFP_KERNEL);
		if (!pdata->rdev) {
			return -ENOMEM;
		}
		/* Instantiate the regulators */
		for (i = 0; i < pdata->num_regulators; i++) {
		reg_data = pwm_pdev->pwm_init_data[i];
		if (!reg_data)
			continue;
		config.dev = &pdev->dev;
		config.driver_data = pdata;
		if (&pdev->dev.of_node)
			config.of_node = pwm_pdev->of_node[i];
		if (reg_data && reg_data->constraints.name)
				rail_name = reg_data->constraints.name;
			else
				rail_name = regulators[i].name;
			reg_data->supply_regulator = rail_name;

		config.init_data = reg_data;

		pwm_rdev = regulator_register(&regulators[i], &config);
		if (IS_ERR(pwm_rdev)) {
			printk("failed to register %d regulator\n", i);
		goto err;
		}
		pdata->rdev[i] = pwm_rdev;

		/*********set pwm vol by defult***********/
		dc = regulator_get(NULL, rail_name);
		regulator_set_voltage(dc, pdata->pwm_voltage, pdata->pwm_voltage);
		regulator_put(dc);
		/**************************************/
		}
	}
	return 0;
err:
	printk("%s:error\n", __func__);
	return ret;

}
示例#12
0
static int max77693_haptic_probe(struct platform_device *pdev)
{
	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
	struct max77693_haptic *haptic;
	int error;

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

	haptic->regmap_pmic = max77693->regmap;
	haptic->regmap_haptic = max77693->regmap_haptic;
	haptic->dev = &pdev->dev;
	haptic->type = MAX77693_HAPTIC_LRA;
	haptic->mode = MAX77693_HAPTIC_EXTERNAL_MODE;
	haptic->pwm_divisor = MAX77693_HAPTIC_PWM_DIVISOR_128;
	haptic->suspend_state = false;

	INIT_WORK(&haptic->work, max77693_haptic_play_work);

	/* Get pwm and regulatot for haptic device */
	haptic->pwm_dev = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(haptic->pwm_dev)) {
		dev_err(&pdev->dev, "failed to get pwm device\n");
		return PTR_ERR(haptic->pwm_dev);
	}

	haptic->motor_reg = devm_regulator_get(&pdev->dev, "haptic");
	if (IS_ERR(haptic->motor_reg)) {
		dev_err(&pdev->dev, "failed to get regulator\n");
		return PTR_ERR(haptic->motor_reg);
	}

	/* Initialize input device for haptic device */
	haptic->input_dev = devm_input_allocate_device(&pdev->dev);
	if (!haptic->input_dev) {
		dev_err(&pdev->dev, "failed to allocate input device\n");
		return -ENOMEM;
	}

	haptic->input_dev->name = "max77693-haptic";
	haptic->input_dev->id.version = 1;
	haptic->input_dev->dev.parent = &pdev->dev;
	haptic->input_dev->open = max77693_haptic_open;
	haptic->input_dev->close = max77693_haptic_close;
	input_set_drvdata(haptic->input_dev, haptic);
	input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);

	error = input_ff_create_memless(haptic->input_dev, NULL,
				max77693_haptic_play_effect);
	if (error) {
		dev_err(&pdev->dev, "failed to create force-feedback\n");
		return error;
	}

	error = input_register_device(haptic->input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to register input device\n");
		return error;
	}

	platform_set_drvdata(pdev, haptic);

	return 0;
}