2019-08-27 06:44:15 +03:00
// SPDX-License-Identifier: GPL-2.0
/*
* Synaptics AS370 SoC Hardware Monitoring Driver
*
* Copyright ( C ) 2018 Synaptics Incorporated
* Author : Jisheng Zhang < jszhang @ kernel . org >
*/
# include <linux/bitops.h>
# include <linux/hwmon.h>
# include <linux/init.h>
# include <linux/io.h>
# include <linux/module.h>
# include <linux/of_device.h>
# define CTRL 0x0
# define PD BIT(0)
# define EN BIT(1)
# define T_SEL BIT(2)
# define V_SEL BIT(3)
# define NMOS_SEL BIT(8)
# define PMOS_SEL BIT(9)
# define STS 0x4
# define BN_MASK GENMASK(11, 0)
# define EOC BIT(12)
struct as370_hwmon {
void __iomem * base ;
} ;
static void init_pvt ( struct as370_hwmon * hwmon )
{
u32 val ;
void __iomem * addr = hwmon - > base + CTRL ;
val = PD ;
writel_relaxed ( val , addr ) ;
val | = T_SEL ;
writel_relaxed ( val , addr ) ;
val | = EN ;
writel_relaxed ( val , addr ) ;
val & = ~ PD ;
writel_relaxed ( val , addr ) ;
}
static int as370_hwmon_read ( struct device * dev , enum hwmon_sensor_types type ,
u32 attr , int channel , long * temp )
{
int val ;
struct as370_hwmon * hwmon = dev_get_drvdata ( dev ) ;
switch ( attr ) {
case hwmon_temp_input :
val = readl_relaxed ( hwmon - > base + STS ) & BN_MASK ;
* temp = DIV_ROUND_CLOSEST ( val * 251802 , 4096 ) - 85525 ;
break ;
default :
return - EOPNOTSUPP ;
}
return 0 ;
}
static umode_t
as370_hwmon_is_visible ( const void * data , enum hwmon_sensor_types type ,
u32 attr , int channel )
{
if ( type ! = hwmon_temp )
return 0 ;
switch ( attr ) {
case hwmon_temp_input :
return 0444 ;
default :
return 0 ;
}
}
static const u32 as370_hwmon_temp_config [ ] = {
HWMON_T_INPUT ,
0
} ;
static const struct hwmon_channel_info as370_hwmon_temp = {
. type = hwmon_temp ,
. config = as370_hwmon_temp_config ,
} ;
static const struct hwmon_channel_info * as370_hwmon_info [ ] = {
& as370_hwmon_temp ,
NULL
} ;
static const struct hwmon_ops as370_hwmon_ops = {
. is_visible = as370_hwmon_is_visible ,
. read = as370_hwmon_read ,
} ;
static const struct hwmon_chip_info as370_chip_info = {
. ops = & as370_hwmon_ops ,
. info = as370_hwmon_info ,
} ;
static int as370_hwmon_probe ( struct platform_device * pdev )
{
struct device * hwmon_dev ;
struct as370_hwmon * hwmon ;
struct device * dev = & pdev - > dev ;
hwmon = devm_kzalloc ( dev , sizeof ( * hwmon ) , GFP_KERNEL ) ;
if ( ! hwmon )
return - ENOMEM ;
2019-09-03 07:47:52 +03:00
hwmon - > base = devm_platform_ioremap_resource ( pdev , 0 ) ;
2019-08-27 06:44:15 +03:00
if ( IS_ERR ( hwmon - > base ) )
return PTR_ERR ( hwmon - > base ) ;
init_pvt ( hwmon ) ;
hwmon_dev = devm_hwmon_device_register_with_info ( dev ,
" as370 " ,
hwmon ,
& as370_chip_info ,
NULL ) ;
return PTR_ERR_OR_ZERO ( hwmon_dev ) ;
}
static const struct of_device_id as370_hwmon_match [ ] = {
{ . compatible = " syna,as370-hwmon " } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , as370_hwmon_match ) ;
static struct platform_driver as370_hwmon_driver = {
. probe = as370_hwmon_probe ,
. driver = {
. name = " as370-hwmon " ,
. of_match_table = as370_hwmon_match ,
} ,
} ;
module_platform_driver ( as370_hwmon_driver ) ;
MODULE_AUTHOR ( " Jisheng Zhang<jszhang@kernel.org> " ) ;
MODULE_DESCRIPTION ( " Synaptics AS370 SoC hardware monitor " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;