forked from mirrors/linux
		
	pwm: Add PWM driver for OMAP using dual-mode timers
Adds support for using a OMAP dual-mode timer with PWM capability as a Linux PWM device. The driver controls the timer by using the dmtimer API. Add a platform_data structure for each pwm-omap-dmtimer nodes containing the dmtimers functions in order to get driver not rely on platform specific functions. Cc: Grant Erickson <marathon96@gmail.com> Cc: NeilBrown <neilb@suse.de> Cc: Joachim Eastwood <manabian@gmail.com> Suggested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com> Acked-by: Tony Lindgren <tony@atomide.com> [thierry.reding@gmail.com: coding style bikeshed, fix timer leak] Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
This commit is contained in:
		
							parent
							
								
									72c16a9f98
								
							
						
					
					
						commit
						6604c6556d
					
				
					 5 changed files with 424 additions and 0 deletions
				
			
		
							
								
								
									
										18
									
								
								Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| * OMAP PWM for dual-mode timers | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible: Shall contain "ti,omap-dmtimer-pwm". | ||||
| - ti,timers: phandle to PWM capable OMAP timer. See arm/omap/timer.txt for info | ||||
|   about these timers. | ||||
| - #pwm-cells: Should be 3. See pwm.txt in this directory for a description of | ||||
|   the cells format. | ||||
| 
 | ||||
| Optional properties: | ||||
| - ti,prescaler: Should be a value between 0 and 7, see the timers datasheet | ||||
| 
 | ||||
| Example: | ||||
| 	pwm9: dmtimer-pwm@9 { | ||||
| 		compatible = "ti,omap-dmtimer-pwm"; | ||||
| 		ti,timers = <&timer9>; | ||||
| 		#pwm-cells = <3>; | ||||
| 	}; | ||||
|  | @ -265,6 +265,15 @@ config PWM_MXS | |||
| 	  To compile this driver as a module, choose M here: the module | ||||
| 	  will be called pwm-mxs. | ||||
| 
 | ||||
| config PWM_OMAP_DMTIMER | ||||
| 	tristate "OMAP Dual-Mode Timer PWM support" | ||||
| 	depends on OF && ARCH_OMAP && OMAP_DM_TIMER | ||||
| 	help | ||||
| 	  Generic PWM framework driver for OMAP Dual-Mode Timer PWM output | ||||
| 
 | ||||
| 	  To compile this driver as a module, choose M here: the module | ||||
| 	  will be called pwm-omap-dmtimer | ||||
| 
 | ||||
| config PWM_PCA9685 | ||||
| 	tristate "NXP PCA9685 PWM driver" | ||||
| 	depends on I2C | ||||
|  |  | |||
|  | @ -24,6 +24,7 @@ obj-$(CONFIG_PWM_LPSS_PCI)	+= pwm-lpss-pci.o | |||
| obj-$(CONFIG_PWM_LPSS_PLATFORM)	+= pwm-lpss-platform.o | ||||
| obj-$(CONFIG_PWM_MTK_DISP)	+= pwm-mtk-disp.o | ||||
| obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o | ||||
| obj-$(CONFIG_PWM_OMAP_DMTIMER)	+= pwm-omap-dmtimer.o | ||||
| obj-$(CONFIG_PWM_PCA9685)	+= pwm-pca9685.o | ||||
| obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o | ||||
| obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o | ||||
|  |  | |||
							
								
								
									
										327
									
								
								drivers/pwm/pwm-omap-dmtimer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								drivers/pwm/pwm-omap-dmtimer.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,327 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2015 Neil Armstrong <narmstrong@baylibre.com> | ||||
|  * Copyright (c) 2014 Joachim Eastwood <manabian@gmail.com> | ||||
|  * Copyright (c) 2012 NeilBrown <neilb@suse.de> | ||||
|  * Heavily based on earlier code which is: | ||||
|  * Copyright (c) 2010 Grant Erickson <marathon96@gmail.com> | ||||
|  * | ||||
|  * Also based on pwm-samsung.c | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 as published by the Free Software Foundation. | ||||
|  * | ||||
|  * Description: | ||||
|  *   This file is the core OMAP support for the generic, Linux | ||||
|  *   PWM driver / controller, using the OMAP's dual-mode timers. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/clk.h> | ||||
| #include <linux/err.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_platform.h> | ||||
| #include <linux/platform_data/pwm_omap_dmtimer.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/pm_runtime.h> | ||||
| #include <linux/pwm.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/time.h> | ||||
| 
 | ||||
| #define DM_TIMER_LOAD_MIN 0xfffffffe | ||||
| 
 | ||||
| struct pwm_omap_dmtimer_chip { | ||||
| 	struct pwm_chip chip; | ||||
| 	struct mutex mutex; | ||||
| 	pwm_omap_dmtimer *dm_timer; | ||||
| 	struct pwm_omap_dmtimer_pdata *pdata; | ||||
| 	struct platform_device *dm_timer_pdev; | ||||
| }; | ||||
| 
 | ||||
| static inline struct pwm_omap_dmtimer_chip * | ||||
| to_pwm_omap_dmtimer_chip(struct pwm_chip *chip) | ||||
| { | ||||
| 	return container_of(chip, struct pwm_omap_dmtimer_chip, chip); | ||||
| } | ||||
| 
 | ||||
| static int pwm_omap_dmtimer_calc_value(unsigned long clk_rate, int ns) | ||||
| { | ||||
| 	u64 c = (u64)clk_rate * ns; | ||||
| 
 | ||||
| 	do_div(c, NSEC_PER_SEC); | ||||
| 
 | ||||
| 	return DM_TIMER_LOAD_MIN - c; | ||||
| } | ||||
| 
 | ||||
| static void pwm_omap_dmtimer_start(struct pwm_omap_dmtimer_chip *omap) | ||||
| { | ||||
| 	/*
 | ||||
| 	 * According to OMAP 4 TRM section 22.2.4.10 the counter should be | ||||
| 	 * started at 0xFFFFFFFE when overflow and match is used to ensure | ||||
| 	 * that the PWM line is toggled on the first event. | ||||
| 	 * | ||||
| 	 * Note that omap_dm_timer_enable/disable is for register access and | ||||
| 	 * not the timer counter itself. | ||||
| 	 */ | ||||
| 	omap->pdata->enable(omap->dm_timer); | ||||
| 	omap->pdata->write_counter(omap->dm_timer, DM_TIMER_LOAD_MIN); | ||||
| 	omap->pdata->disable(omap->dm_timer); | ||||
| 
 | ||||
| 	omap->pdata->start(omap->dm_timer); | ||||
| } | ||||
| 
 | ||||
| static int pwm_omap_dmtimer_enable(struct pwm_chip *chip, | ||||
| 				   struct pwm_device *pwm) | ||||
| { | ||||
| 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); | ||||
| 
 | ||||
| 	mutex_lock(&omap->mutex); | ||||
| 	pwm_omap_dmtimer_start(omap); | ||||
| 	mutex_unlock(&omap->mutex); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void pwm_omap_dmtimer_disable(struct pwm_chip *chip, | ||||
| 				     struct pwm_device *pwm) | ||||
| { | ||||
| 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); | ||||
| 
 | ||||
| 	mutex_lock(&omap->mutex); | ||||
| 	omap->pdata->stop(omap->dm_timer); | ||||
| 	mutex_unlock(&omap->mutex); | ||||
| } | ||||
| 
 | ||||
| static int pwm_omap_dmtimer_config(struct pwm_chip *chip, | ||||
| 				   struct pwm_device *pwm, | ||||
| 				   int duty_ns, int period_ns) | ||||
| { | ||||
| 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); | ||||
| 	int load_value, match_value; | ||||
| 	struct clk *fclk; | ||||
| 	unsigned long clk_rate; | ||||
| 	bool timer_active; | ||||
| 
 | ||||
| 	dev_dbg(chip->dev, "duty cycle: %d, period %d\n", duty_ns, period_ns); | ||||
| 
 | ||||
| 	mutex_lock(&omap->mutex); | ||||
| 	if (duty_ns == pwm_get_duty_cycle(pwm) && | ||||
| 	    period_ns == pwm_get_period(pwm)) { | ||||
| 		/* No change - don't cause any transients. */ | ||||
| 		mutex_unlock(&omap->mutex); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	fclk = omap->pdata->get_fclk(omap->dm_timer); | ||||
| 	if (!fclk) { | ||||
| 		dev_err(chip->dev, "invalid pmtimer fclk\n"); | ||||
| 		mutex_unlock(&omap->mutex); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	clk_rate = clk_get_rate(fclk); | ||||
| 	if (!clk_rate) { | ||||
| 		dev_err(chip->dev, "invalid pmtimer fclk rate\n"); | ||||
| 		mutex_unlock(&omap->mutex); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	dev_dbg(chip->dev, "clk rate: %luHz\n", clk_rate); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Calculate the appropriate load and match values based on the | ||||
| 	 * specified period and duty cycle. The load value determines the | ||||
| 	 * cycle time and the match value determines the duty cycle. | ||||
| 	 */ | ||||
| 	load_value = pwm_omap_dmtimer_calc_value(clk_rate, period_ns); | ||||
| 	match_value = pwm_omap_dmtimer_calc_value(clk_rate, | ||||
| 						  period_ns - duty_ns); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We MUST stop the associated dual-mode timer before attempting to | ||||
| 	 * write its registers, but calls to omap_dm_timer_start/stop must | ||||
| 	 * be balanced so check if timer is active before calling timer_stop. | ||||
| 	 */ | ||||
| 	timer_active = pm_runtime_active(&omap->dm_timer_pdev->dev); | ||||
| 	if (timer_active) | ||||
| 		omap->pdata->stop(omap->dm_timer); | ||||
| 
 | ||||
| 	omap->pdata->set_load(omap->dm_timer, true, load_value); | ||||
| 	omap->pdata->set_match(omap->dm_timer, true, match_value); | ||||
| 
 | ||||
| 	dev_dbg(chip->dev, "load value: %#08x (%d), match value: %#08x (%d)\n", | ||||
| 		load_value, load_value,	match_value, match_value); | ||||
| 
 | ||||
| 	omap->pdata->set_pwm(omap->dm_timer, | ||||
| 			      pwm->polarity == PWM_POLARITY_INVERSED, | ||||
| 			      true, | ||||
| 			      PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); | ||||
| 
 | ||||
| 	/* If config was called while timer was running it must be reenabled. */ | ||||
| 	if (timer_active) | ||||
| 		pwm_omap_dmtimer_start(omap); | ||||
| 
 | ||||
| 	mutex_unlock(&omap->mutex); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int pwm_omap_dmtimer_set_polarity(struct pwm_chip *chip, | ||||
| 					 struct pwm_device *pwm, | ||||
| 					 enum pwm_polarity polarity) | ||||
| { | ||||
| 	struct pwm_omap_dmtimer_chip *omap = to_pwm_omap_dmtimer_chip(chip); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * PWM core will not call set_polarity while PWM is enabled so it's | ||||
| 	 * safe to reconfigure the timer here without stopping it first. | ||||
| 	 */ | ||||
| 	mutex_lock(&omap->mutex); | ||||
| 	omap->pdata->set_pwm(omap->dm_timer, | ||||
| 			      polarity == PWM_POLARITY_INVERSED, | ||||
| 			      true, | ||||
| 			      PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE); | ||||
| 	mutex_unlock(&omap->mutex); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct pwm_ops pwm_omap_dmtimer_ops = { | ||||
| 	.enable	= pwm_omap_dmtimer_enable, | ||||
| 	.disable = pwm_omap_dmtimer_disable, | ||||
| 	.config	= pwm_omap_dmtimer_config, | ||||
| 	.set_polarity = pwm_omap_dmtimer_set_polarity, | ||||
| 	.owner = THIS_MODULE, | ||||
| }; | ||||
| 
 | ||||
| static int pwm_omap_dmtimer_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct device_node *np = pdev->dev.of_node; | ||||
| 	struct device_node *timer; | ||||
| 	struct pwm_omap_dmtimer_chip *omap; | ||||
| 	struct pwm_omap_dmtimer_pdata *pdata; | ||||
| 	pwm_omap_dmtimer *dm_timer; | ||||
| 	u32 prescaler; | ||||
| 	int status; | ||||
| 
 | ||||
| 	pdata = dev_get_platdata(&pdev->dev); | ||||
| 	if (!pdata) { | ||||
| 		dev_err(&pdev->dev, "Missing dmtimer platform data\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!pdata->request_by_node || | ||||
| 	    !pdata->free || | ||||
| 	    !pdata->enable || | ||||
| 	    !pdata->disable || | ||||
| 	    !pdata->get_fclk || | ||||
| 	    !pdata->start || | ||||
| 	    !pdata->stop || | ||||
| 	    !pdata->set_load || | ||||
| 	    !pdata->set_match || | ||||
| 	    !pdata->set_pwm || | ||||
| 	    !pdata->set_prescaler || | ||||
| 	    !pdata->write_counter) { | ||||
| 		dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	timer = of_parse_phandle(np, "ti,timers", 0); | ||||
| 	if (!timer) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	if (!of_get_property(timer, "ti,timer-pwm", NULL)) { | ||||
| 		dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	dm_timer = pdata->request_by_node(timer); | ||||
| 	if (!dm_timer) | ||||
| 		return -EPROBE_DEFER; | ||||
| 
 | ||||
| 	omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); | ||||
| 	if (!omap) { | ||||
| 		omap->pdata->free(dm_timer); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	omap->pdata = pdata; | ||||
| 	omap->dm_timer = dm_timer; | ||||
| 
 | ||||
| 	omap->dm_timer_pdev = of_find_device_by_node(timer); | ||||
| 	if (!omap->dm_timer_pdev) { | ||||
| 		dev_err(&pdev->dev, "Unable to find timer pdev\n"); | ||||
| 		omap->pdata->free(dm_timer); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Ensure that the timer is stopped before we allow PWM core to call | ||||
| 	 * pwm_enable. | ||||
| 	 */ | ||||
| 	if (pm_runtime_active(&omap->dm_timer_pdev->dev)) | ||||
| 		omap->pdata->stop(omap->dm_timer); | ||||
| 
 | ||||
| 	/* setup dmtimer prescaler */ | ||||
| 	if (!of_property_read_u32(pdev->dev.of_node, "ti,prescaler", | ||||
| 				&prescaler)) | ||||
| 		omap->pdata->set_prescaler(omap->dm_timer, prescaler); | ||||
| 
 | ||||
| 	omap->chip.dev = &pdev->dev; | ||||
| 	omap->chip.ops = &pwm_omap_dmtimer_ops; | ||||
| 	omap->chip.base = -1; | ||||
| 	omap->chip.npwm = 1; | ||||
| 	omap->chip.of_xlate = of_pwm_xlate_with_flags; | ||||
| 	omap->chip.of_pwm_n_cells = 3; | ||||
| 
 | ||||
| 	mutex_init(&omap->mutex); | ||||
| 
 | ||||
| 	status = pwmchip_add(&omap->chip); | ||||
| 	if (status < 0) { | ||||
| 		dev_err(&pdev->dev, "failed to register PWM\n"); | ||||
| 		omap->pdata->free(omap->dm_timer); | ||||
| 		return status; | ||||
| 	} | ||||
| 
 | ||||
| 	platform_set_drvdata(pdev, omap); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int pwm_omap_dmtimer_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev); | ||||
| 
 | ||||
| 	if (pm_runtime_active(&omap->dm_timer_pdev->dev)) | ||||
| 		omap->pdata->stop(omap->dm_timer); | ||||
| 
 | ||||
| 	omap->pdata->free(omap->dm_timer); | ||||
| 
 | ||||
| 	mutex_destroy(&omap->mutex); | ||||
| 
 | ||||
| 	return pwmchip_remove(&omap->chip); | ||||
| } | ||||
| 
 | ||||
| static const struct of_device_id pwm_omap_dmtimer_of_match[] = { | ||||
| 	{.compatible = "ti,omap-dmtimer-pwm"}, | ||||
| 	{} | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match); | ||||
| 
 | ||||
| static struct platform_driver pwm_omap_dmtimer_driver = { | ||||
| 	.driver = { | ||||
| 		.name = "omap-dmtimer-pwm", | ||||
| 		.of_match_table = of_match_ptr(pwm_omap_dmtimer_of_match), | ||||
| 	}, | ||||
| 	.probe = pwm_omap_dmtimer_probe, | ||||
| 	.remove	= pwm_omap_dmtimer_remove, | ||||
| }; | ||||
| module_platform_driver(pwm_omap_dmtimer_driver); | ||||
| 
 | ||||
| MODULE_AUTHOR("Grant Erickson <marathon96@gmail.com>"); | ||||
| MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); | ||||
| MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); | ||||
| MODULE_LICENSE("GPL v2"); | ||||
| MODULE_DESCRIPTION("OMAP PWM Driver using Dual-mode Timers"); | ||||
							
								
								
									
										69
									
								
								include/linux/platform_data/pwm_omap_dmtimer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								include/linux/platform_data/pwm_omap_dmtimer.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,69 @@ | |||
| /*
 | ||||
|  * include/linux/platform_data/pwm_omap_dmtimer.h | ||||
|  * | ||||
|  * OMAP Dual-Mode Timer PWM platform data | ||||
|  * | ||||
|  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
 | ||||
|  * Tarun Kanti DebBarma <tarun.kanti@ti.com> | ||||
|  * Thara Gopinath <thara@ti.com> | ||||
|  * | ||||
|  * Platform device conversion and hwmod support. | ||||
|  * | ||||
|  * Copyright (C) 2005 Nokia Corporation | ||||
|  * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com> | ||||
|  * PWM and clock framework support by Timo Teras. | ||||
|  * | ||||
|  * 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; either version 2 of the License, or (at your | ||||
|  * option) any later version. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||||
|  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||||
|  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||||
|  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
|  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||
|  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
|  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * | ||||
|  * You should have received a copy of the  GNU General Public License along | ||||
|  * with this program; if not, write  to the Free Software Foundation, Inc., | ||||
|  * 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __PWM_OMAP_DMTIMER_PDATA_H | ||||
| #define __PWM_OMAP_DMTIMER_PDATA_H | ||||
| 
 | ||||
| /* trigger types */ | ||||
| #define PWM_OMAP_DMTIMER_TRIGGER_NONE			0x00 | ||||
| #define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW		0x01 | ||||
| #define PWM_OMAP_DMTIMER_TRIGGER_OVERFLOW_AND_COMPARE	0x02 | ||||
| 
 | ||||
| struct omap_dm_timer; | ||||
| typedef struct omap_dm_timer pwm_omap_dmtimer; | ||||
| 
 | ||||
| struct pwm_omap_dmtimer_pdata { | ||||
| 	pwm_omap_dmtimer *(*request_by_node)(struct device_node *np); | ||||
| 	int	(*free)(pwm_omap_dmtimer *timer); | ||||
| 
 | ||||
| 	void	(*enable)(pwm_omap_dmtimer *timer); | ||||
| 	void	(*disable)(pwm_omap_dmtimer *timer); | ||||
| 
 | ||||
| 	struct clk *(*get_fclk)(pwm_omap_dmtimer *timer); | ||||
| 
 | ||||
| 	int	(*start)(pwm_omap_dmtimer *timer); | ||||
| 	int	(*stop)(pwm_omap_dmtimer *timer); | ||||
| 
 | ||||
| 	int	(*set_load)(pwm_omap_dmtimer *timer, int autoreload, | ||||
| 			unsigned int value); | ||||
| 	int	(*set_match)(pwm_omap_dmtimer *timer, int enable, | ||||
| 			unsigned int match); | ||||
| 	int	(*set_pwm)(pwm_omap_dmtimer *timer, int def_on, | ||||
| 			int toggle, int trigger); | ||||
| 	int	(*set_prescaler)(pwm_omap_dmtimer *timer, int prescaler); | ||||
| 
 | ||||
| 	int	(*write_counter)(pwm_omap_dmtimer *timer, unsigned int value); | ||||
| }; | ||||
| 
 | ||||
| #endif /* __PWM_OMAP_DMTIMER_PDATA_H */ | ||||
		Loading…
	
		Reference in a new issue
	
	 Neil Armstrong
						Neil Armstrong