2019-05-28 19:57:21 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2010-09-06 10:54:52 +04:00
/*
* Copyright ( C ) ST - Ericsson SA 2010
*
* Author : Arun R Murthy < arun . murthy @ stericsson . com >
*/
# include <linux/err.h>
# include <linux/platform_device.h>
# include <linux/slab.h>
# include <linux/pwm.h>
# include <linux/mfd/abx500.h>
2011-12-02 17:16:33 +04:00
# include <linux/mfd/abx500/ab8500.h>
2011-07-03 23:14:56 +04:00
# include <linux/module.h>
2010-09-06 10:54:52 +04:00
/*
* PWM Out generators
* Bank : 0x10
*/
# define AB8500_PWM_OUT_CTRL1_REG 0x60
# define AB8500_PWM_OUT_CTRL2_REG 0x61
# define AB8500_PWM_OUT_CTRL7_REG 0x66
2012-08-31 13:46:24 +04:00
struct ab8500_pwm_chip {
struct pwm_chip chip ;
2021-07-05 19:55:10 +03:00
unsigned int hwid ;
2010-09-06 10:54:52 +04:00
} ;
2021-07-05 19:55:10 +03:00
static struct ab8500_pwm_chip * ab8500_pwm_from_chip ( struct pwm_chip * chip )
{
return container_of ( chip , struct ab8500_pwm_chip , chip ) ;
}
2021-03-01 21:45:37 +03:00
static int ab8500_pwm_apply ( struct pwm_chip * chip , struct pwm_device * pwm ,
const struct pwm_state * state )
2010-09-06 10:54:52 +04:00
{
2021-03-01 21:45:37 +03:00
int ret ;
2010-09-06 10:54:52 +04:00
u8 reg ;
2021-03-01 21:45:37 +03:00
unsigned int higher_val , lower_val ;
2021-07-05 19:55:10 +03:00
struct ab8500_pwm_chip * ab8500 = ab8500_pwm_from_chip ( chip ) ;
2021-03-01 21:45:37 +03:00
if ( state - > polarity ! = PWM_POLARITY_NORMAL )
return - EINVAL ;
if ( ! state - > enabled ) {
ret = abx500_mask_and_set_register_interruptible ( chip - > dev ,
AB8500_MISC , AB8500_PWM_OUT_CTRL7_REG ,
2021-07-05 19:55:10 +03:00
1 < < ab8500 - > hwid , 0 ) ;
2021-03-01 21:45:37 +03:00
if ( ret < 0 )
dev_err ( chip - > dev , " %s: Failed to disable PWM, Error %d \n " ,
pwm - > label , ret ) ;
return ret ;
}
2010-09-06 10:54:52 +04:00
/*
* get the first 8 bits that are be written to
* AB8500_PWM_OUT_CTRL1_REG [ 0 : 7 ]
*/
2021-03-01 21:45:37 +03:00
lower_val = state - > duty_cycle & 0x00FF ;
2010-09-06 10:54:52 +04:00
/*
* get bits [ 9 : 10 ] that are to be written to
* AB8500_PWM_OUT_CTRL2_REG [ 0 : 1 ]
*/
2021-03-01 21:45:37 +03:00
higher_val = ( ( state - > duty_cycle & 0x0300 ) > > 8 ) ;
2010-09-06 10:54:52 +04:00
2021-07-05 19:55:10 +03:00
reg = AB8500_PWM_OUT_CTRL1_REG + ( ab8500 - > hwid * 2 ) ;
2010-09-06 10:54:52 +04:00
2012-08-31 13:46:24 +04:00
ret = abx500_set_register_interruptible ( chip - > dev , AB8500_MISC ,
2010-09-06 10:54:52 +04:00
reg , ( u8 ) lower_val ) ;
if ( ret < 0 )
return ret ;
2021-03-01 21:45:37 +03:00
2012-08-31 13:46:24 +04:00
ret = abx500_set_register_interruptible ( chip - > dev , AB8500_MISC ,
2010-09-06 10:54:52 +04:00
( reg + 1 ) , ( u8 ) higher_val ) ;
2021-03-01 21:45:37 +03:00
if ( ret < 0 )
return ret ;
2010-09-06 10:54:52 +04:00
2012-08-31 13:46:24 +04:00
ret = abx500_mask_and_set_register_interruptible ( chip - > dev ,
2010-09-06 10:54:52 +04:00
AB8500_MISC , AB8500_PWM_OUT_CTRL7_REG ,
2021-07-05 19:55:10 +03:00
1 < < ab8500 - > hwid , 1 < < ab8500 - > hwid ) ;
2010-09-06 10:54:52 +04:00
if ( ret < 0 )
2013-03-26 18:34:50 +04:00
dev_err ( chip - > dev , " %s: Failed to enable PWM, Error %d \n " ,
2010-09-06 10:54:52 +04:00
pwm - > label , ret ) ;
2021-03-01 21:45:37 +03:00
return ret ;
2010-09-06 10:54:52 +04:00
}
2012-08-31 13:46:24 +04:00
static const struct pwm_ops ab8500_pwm_ops = {
2021-03-01 21:45:37 +03:00
. apply = ab8500_pwm_apply ,
2013-03-31 07:14:02 +04:00
. owner = THIS_MODULE ,
2012-08-31 13:46:24 +04:00
} ;
2010-09-06 10:54:52 +04:00
2012-11-19 22:23:14 +04:00
static int ab8500_pwm_probe ( struct platform_device * pdev )
2010-09-06 10:54:52 +04:00
{
2012-08-31 13:46:24 +04:00
struct ab8500_pwm_chip * ab8500 ;
int err ;
2021-07-05 19:55:10 +03:00
if ( pdev - > id < 1 | | pdev - > id > 31 )
return dev_err_probe ( & pdev - > dev , EINVAL , " Invalid device id %d \n " , pdev - > id ) ;
2010-09-06 10:54:52 +04:00
/*
* Nothing to be done in probe , this is required to get the
* device which is required for ab8500 read and write
*/
2013-03-08 07:45:58 +04:00
ab8500 = devm_kzalloc ( & pdev - > dev , sizeof ( * ab8500 ) , GFP_KERNEL ) ;
2014-04-23 13:39:26 +04:00
if ( ab8500 = = NULL )
2010-09-06 10:54:52 +04:00
return - ENOMEM ;
2012-08-31 13:46:24 +04:00
ab8500 - > chip . dev = & pdev - > dev ;
ab8500 - > chip . ops = & ab8500_pwm_ops ;
ab8500 - > chip . npwm = 1 ;
2021-07-05 19:55:10 +03:00
ab8500 - > hwid = pdev - > id - 1 ;
2012-08-31 13:46:24 +04:00
2021-07-07 19:28:00 +03:00
err = devm_pwmchip_add ( & pdev - > dev , & ab8500 - > chip ) ;
2013-03-08 07:45:58 +04:00
if ( err < 0 )
2020-08-12 10:52:14 +03:00
return dev_err_probe ( & pdev - > dev , err , " Failed to add pwm chip \n " ) ;
2012-08-31 13:46:24 +04:00
dev_dbg ( & pdev - > dev , " pwm probe successful \n " ) ;
2010-09-06 10:54:52 +04:00
return 0 ;
}
static struct platform_driver ab8500_pwm_driver = {
. driver = {
. name = " ab8500-pwm " ,
} ,
. probe = ab8500_pwm_probe ,
} ;
2012-08-31 13:46:24 +04:00
module_platform_driver ( ab8500_pwm_driver ) ;
2010-09-06 10:54:52 +04:00
MODULE_AUTHOR ( " Arun MURTHY <arun.murthy@stericsson.com> " ) ;
MODULE_DESCRIPTION ( " AB8500 Pulse Width Modulation Driver " ) ;
2011-08-26 02:59:20 +04:00
MODULE_ALIAS ( " platform:ab8500-pwm " ) ;
2010-09-06 10:54:52 +04:00
MODULE_LICENSE ( " GPL v2 " ) ;