| /* | 
 |  * TI/National Semiconductor LP3943 PWM driver | 
 |  * | 
 |  * Copyright 2013 Texas Instruments | 
 |  * | 
 |  * Author: Milo Kim <milo.kim@ti.com> | 
 |  * | 
 |  * This program is free software; you can redistribute it and/or modify | 
 |  * it under the terms of the GNU General Public License as published by | 
 |  * the Free Software Foundation; version 2. | 
 |  */ | 
 |  | 
 | #include <linux/err.h> | 
 | #include <linux/i2c.h> | 
 | #include <linux/mfd/lp3943.h> | 
 | #include <linux/module.h> | 
 | #include <linux/platform_device.h> | 
 | #include <linux/pwm.h> | 
 | #include <linux/slab.h> | 
 |  | 
 | #define LP3943_MAX_DUTY			255 | 
 | #define LP3943_MIN_PERIOD		6250 | 
 | #define LP3943_MAX_PERIOD		1600000 | 
 |  | 
 | struct lp3943_pwm { | 
 | 	struct pwm_chip chip; | 
 | 	struct lp3943 *lp3943; | 
 | 	struct lp3943_platform_data *pdata; | 
 | }; | 
 |  | 
 | static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip) | 
 | { | 
 | 	return container_of(_chip, struct lp3943_pwm, chip); | 
 | } | 
 |  | 
 | static struct lp3943_pwm_map * | 
 | lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm) | 
 | { | 
 | 	struct lp3943_platform_data *pdata = lp3943_pwm->pdata; | 
 | 	struct lp3943 *lp3943 = lp3943_pwm->lp3943; | 
 | 	struct lp3943_pwm_map *pwm_map; | 
 | 	int i, offset; | 
 |  | 
 | 	pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL); | 
 | 	if (!pwm_map) | 
 | 		return ERR_PTR(-ENOMEM); | 
 |  | 
 | 	pwm_map->output = pdata->pwms[hwpwm]->output; | 
 | 	pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs; | 
 |  | 
 | 	for (i = 0; i < pwm_map->num_outputs; i++) { | 
 | 		offset = pwm_map->output[i]; | 
 |  | 
 | 		/* Return an error if the pin is already assigned */ | 
 | 		if (test_and_set_bit(offset, &lp3943->pin_used)) { | 
 | 			kfree(pwm_map); | 
 | 			return ERR_PTR(-EBUSY); | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return pwm_map; | 
 | } | 
 |  | 
 | static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) | 
 | { | 
 | 	struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip); | 
 | 	struct lp3943_pwm_map *pwm_map; | 
 |  | 
 | 	pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm); | 
 | 	if (IS_ERR(pwm_map)) | 
 | 		return PTR_ERR(pwm_map); | 
 |  | 
 | 	return pwm_set_chip_data(pwm, pwm_map); | 
 | } | 
 |  | 
 | static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm, | 
 | 				struct lp3943_pwm_map *pwm_map) | 
 | { | 
 | 	struct lp3943 *lp3943 = lp3943_pwm->lp3943; | 
 | 	int i, offset; | 
 |  | 
 | 	for (i = 0; i < pwm_map->num_outputs; i++) { | 
 | 		offset = pwm_map->output[i]; | 
 | 		clear_bit(offset, &lp3943->pin_used); | 
 | 	} | 
 |  | 
 | 	kfree(pwm_map); | 
 | } | 
 |  | 
 | static void lp3943_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | 
 | { | 
 | 	struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip); | 
 | 	struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm); | 
 |  | 
 | 	lp3943_pwm_free_map(lp3943_pwm, pwm_map); | 
 | } | 
 |  | 
 | static int lp3943_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | 
 | 			     int duty_ns, int period_ns) | 
 | { | 
 | 	struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip); | 
 | 	struct lp3943 *lp3943 = lp3943_pwm->lp3943; | 
 | 	u8 val, reg_duty, reg_prescale; | 
 | 	int err; | 
 |  | 
 | 	/* | 
 | 	 * How to configure the LP3943 PWMs | 
 | 	 * | 
 | 	 * 1) Period = 6250 ~ 1600000 | 
 | 	 * 2) Prescale = period / 6250 -1 | 
 | 	 * 3) Duty = input duty | 
 | 	 * | 
 | 	 * Prescale and duty are register values | 
 | 	 */ | 
 |  | 
 | 	if (pwm->hwpwm == 0) { | 
 | 		reg_prescale = LP3943_REG_PRESCALE0; | 
 | 		reg_duty     = LP3943_REG_PWM0; | 
 | 	} else { | 
 | 		reg_prescale = LP3943_REG_PRESCALE1; | 
 | 		reg_duty     = LP3943_REG_PWM1; | 
 | 	} | 
 |  | 
 | 	period_ns = clamp(period_ns, LP3943_MIN_PERIOD, LP3943_MAX_PERIOD); | 
 | 	val       = (u8)(period_ns / LP3943_MIN_PERIOD - 1); | 
 |  | 
 | 	err = lp3943_write_byte(lp3943, reg_prescale, val); | 
 | 	if (err) | 
 | 		return err; | 
 |  | 
 | 	val = (u8)(duty_ns * LP3943_MAX_DUTY / period_ns); | 
 |  | 
 | 	return lp3943_write_byte(lp3943, reg_duty, val); | 
 | } | 
 |  | 
 | static int lp3943_pwm_set_mode(struct lp3943_pwm *lp3943_pwm, | 
 | 			       struct lp3943_pwm_map *pwm_map, | 
 | 			       u8 val) | 
 | { | 
 | 	struct lp3943 *lp3943 = lp3943_pwm->lp3943; | 
 | 	const struct lp3943_reg_cfg *mux = lp3943->mux_cfg; | 
 | 	int i, index, err; | 
 |  | 
 | 	for (i = 0; i < pwm_map->num_outputs; i++) { | 
 | 		index = pwm_map->output[i]; | 
 | 		err = lp3943_update_bits(lp3943, mux[index].reg, | 
 | 					 mux[index].mask, | 
 | 					 val << mux[index].shift); | 
 | 		if (err) | 
 | 			return err; | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | static int lp3943_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) | 
 | { | 
 | 	struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip); | 
 | 	struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm); | 
 | 	u8 val; | 
 |  | 
 | 	if (pwm->hwpwm == 0) | 
 | 		val = LP3943_DIM_PWM0; | 
 | 	else | 
 | 		val = LP3943_DIM_PWM1; | 
 |  | 
 | 	/* | 
 | 	 * Each PWM generator is set to control any of outputs of LP3943. | 
 | 	 * To enable/disable the PWM, these output pins should be configured. | 
 | 	 */ | 
 |  | 
 | 	return lp3943_pwm_set_mode(lp3943_pwm, pwm_map, val); | 
 | } | 
 |  | 
 | static void lp3943_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | 
 | { | 
 | 	struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip); | 
 | 	struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm); | 
 |  | 
 | 	/* | 
 | 	 * LP3943 outputs are open-drain, so the pin should be configured | 
 | 	 * when the PWM is disabled. | 
 | 	 */ | 
 |  | 
 | 	lp3943_pwm_set_mode(lp3943_pwm, pwm_map, LP3943_GPIO_OUT_HIGH); | 
 | } | 
 |  | 
 | static const struct pwm_ops lp3943_pwm_ops = { | 
 | 	.request	= lp3943_pwm_request, | 
 | 	.free		= lp3943_pwm_free, | 
 | 	.config		= lp3943_pwm_config, | 
 | 	.enable		= lp3943_pwm_enable, | 
 | 	.disable	= lp3943_pwm_disable, | 
 | 	.owner		= THIS_MODULE, | 
 | }; | 
 |  | 
 | static int lp3943_pwm_parse_dt(struct device *dev, | 
 | 			       struct lp3943_pwm *lp3943_pwm) | 
 | { | 
 | 	static const char * const name[] = { "ti,pwm0", "ti,pwm1", }; | 
 | 	struct device_node *node = dev->of_node; | 
 | 	struct lp3943_platform_data *pdata; | 
 | 	struct lp3943_pwm_map *pwm_map; | 
 | 	enum lp3943_pwm_output *output; | 
 | 	int i, err, proplen, count = 0; | 
 | 	u32 num_outputs; | 
 |  | 
 | 	if (!node) | 
 | 		return -EINVAL; | 
 |  | 
 | 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | 
 | 	if (!pdata) | 
 | 		return -ENOMEM; | 
 |  | 
 | 	/* | 
 | 	 * Read the output map configuration from the device tree. | 
 | 	 * Each of the two PWM generators can drive zero or more outputs. | 
 | 	 */ | 
 |  | 
 | 	for (i = 0; i < LP3943_NUM_PWMS; i++) { | 
 | 		if (!of_get_property(node, name[i], &proplen)) | 
 | 			continue; | 
 |  | 
 | 		num_outputs = proplen / sizeof(u32); | 
 | 		if (num_outputs == 0) | 
 | 			continue; | 
 |  | 
 | 		output = devm_kcalloc(dev, num_outputs, sizeof(*output), | 
 | 				      GFP_KERNEL); | 
 | 		if (!output) | 
 | 			return -ENOMEM; | 
 |  | 
 | 		err = of_property_read_u32_array(node, name[i], output, | 
 | 						 num_outputs); | 
 | 		if (err) | 
 | 			return err; | 
 |  | 
 | 		pwm_map = devm_kzalloc(dev, sizeof(*pwm_map), GFP_KERNEL); | 
 | 		if (!pwm_map) | 
 | 			return -ENOMEM; | 
 |  | 
 | 		pwm_map->output = output; | 
 | 		pwm_map->num_outputs = num_outputs; | 
 | 		pdata->pwms[i] = pwm_map; | 
 |  | 
 | 		count++; | 
 | 	} | 
 |  | 
 | 	if (count == 0) | 
 | 		return -ENODATA; | 
 |  | 
 | 	lp3943_pwm->pdata = pdata; | 
 | 	return 0; | 
 | } | 
 |  | 
 | static int lp3943_pwm_probe(struct platform_device *pdev) | 
 | { | 
 | 	struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent); | 
 | 	struct lp3943_pwm *lp3943_pwm; | 
 | 	int ret; | 
 |  | 
 | 	lp3943_pwm = devm_kzalloc(&pdev->dev, sizeof(*lp3943_pwm), GFP_KERNEL); | 
 | 	if (!lp3943_pwm) | 
 | 		return -ENOMEM; | 
 |  | 
 | 	lp3943_pwm->pdata = lp3943->pdata; | 
 | 	if (!lp3943_pwm->pdata) { | 
 | 		if (IS_ENABLED(CONFIG_OF)) | 
 | 			ret = lp3943_pwm_parse_dt(&pdev->dev, lp3943_pwm); | 
 | 		else | 
 | 			ret = -ENODEV; | 
 |  | 
 | 		if (ret) | 
 | 			return ret; | 
 | 	} | 
 |  | 
 | 	lp3943_pwm->lp3943 = lp3943; | 
 | 	lp3943_pwm->chip.dev = &pdev->dev; | 
 | 	lp3943_pwm->chip.ops = &lp3943_pwm_ops; | 
 | 	lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; | 
 |  | 
 | 	platform_set_drvdata(pdev, lp3943_pwm); | 
 |  | 
 | 	return pwmchip_add(&lp3943_pwm->chip); | 
 | } | 
 |  | 
 | static int lp3943_pwm_remove(struct platform_device *pdev) | 
 | { | 
 | 	struct lp3943_pwm *lp3943_pwm = platform_get_drvdata(pdev); | 
 |  | 
 | 	return pwmchip_remove(&lp3943_pwm->chip); | 
 | } | 
 |  | 
 | #ifdef CONFIG_OF | 
 | static const struct of_device_id lp3943_pwm_of_match[] = { | 
 | 	{ .compatible = "ti,lp3943-pwm", }, | 
 | 	{ } | 
 | }; | 
 | MODULE_DEVICE_TABLE(of, lp3943_pwm_of_match); | 
 | #endif | 
 |  | 
 | static struct platform_driver lp3943_pwm_driver = { | 
 | 	.probe = lp3943_pwm_probe, | 
 | 	.remove = lp3943_pwm_remove, | 
 | 	.driver = { | 
 | 		.name = "lp3943-pwm", | 
 | 		.of_match_table = of_match_ptr(lp3943_pwm_of_match), | 
 | 	}, | 
 | }; | 
 | module_platform_driver(lp3943_pwm_driver); | 
 |  | 
 | MODULE_DESCRIPTION("LP3943 PWM driver"); | 
 | MODULE_ALIAS("platform:lp3943-pwm"); | 
 | MODULE_AUTHOR("Milo Kim"); | 
 | MODULE_LICENSE("GPL"); |