2019-06-03 08:45:03 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2006-02-08 08:42:51 +03:00
/*
* Windfarm PowerMac thermal control . MAX6690 sensor .
*
* Copyright ( C ) 2005 Paul Mackerras , IBM Corp . < paulus @ samba . org >
*/
# include <linux/types.h>
# include <linux/errno.h>
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/i2c.h>
2022-04-01 20:15:53 +03:00
2006-02-08 08:42:51 +03:00
# include <asm/pmac_low_i2c.h>
# include "windfarm.h"
2012-04-19 02:16:45 +04:00
# define VERSION "1.0"
2006-02-08 08:42:51 +03:00
/* This currently only exports the external temperature sensor,
since that ' s all the control loops need . */
/* Some MAX6690 register numbers */
# define MAX6690_INTERNAL_TEMP 0
# define MAX6690_EXTERNAL_TEMP 1
struct wf_6690_sensor {
2009-06-15 20:01:51 +04:00
struct i2c_client * i2c ;
2006-02-08 08:42:51 +03:00
struct wf_sensor sens ;
} ;
# define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens)
static int wf_max6690_get ( struct wf_sensor * sr , s32 * value )
{
struct wf_6690_sensor * max = wf_to_6690 ( sr ) ;
s32 data ;
2009-06-15 20:01:51 +04:00
if ( max - > i2c = = NULL )
2006-02-08 08:42:51 +03:00
return - ENODEV ;
/* chip gets initialized by firmware */
2009-06-15 20:01:51 +04:00
data = i2c_smbus_read_byte_data ( max - > i2c , MAX6690_EXTERNAL_TEMP ) ;
2006-02-08 08:42:51 +03:00
if ( data < 0 )
return data ;
* value = data < < 16 ;
return 0 ;
}
static void wf_max6690_release ( struct wf_sensor * sr )
{
struct wf_6690_sensor * max = wf_to_6690 ( sr ) ;
kfree ( max ) ;
}
2017-08-03 00:01:45 +03:00
static const struct wf_sensor_ops wf_max6690_ops = {
2006-02-08 08:42:51 +03:00
. get_value = wf_max6690_get ,
. release = wf_max6690_release ,
. owner = THIS_MODULE ,
} ;
2009-06-15 20:01:51 +04:00
static int wf_max6690_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
2006-02-08 08:42:51 +03:00
{
2012-04-19 02:16:45 +04:00
const char * name , * loc ;
2006-02-08 08:42:51 +03:00
struct wf_6690_sensor * max ;
2009-06-15 20:01:51 +04:00
int rc ;
2006-02-08 08:42:51 +03:00
2012-04-19 02:16:45 +04:00
loc = of_get_property ( client - > dev . of_node , " hwsensor-location " , NULL ) ;
if ( ! loc ) {
dev_warn ( & client - > dev , " Missing hwsensor-location property! \n " ) ;
return - ENXIO ;
}
2012-04-19 02:16:54 +04:00
/*
* We only expose the external temperature register for
* now as this is all we need for our control loops
*/
if ( ! strcmp ( loc , " BACKSIDE " ) | | ! strcmp ( loc , " SYS CTRLR AMBIENT " ) )
2012-04-19 02:16:45 +04:00
name = " backside-temp " ;
else if ( ! strcmp ( loc , " NB Ambient " ) )
name = " north-bridge-temp " ;
else if ( ! strcmp ( loc , " GPU Ambient " ) )
name = " gpu-temp " ;
else
return - ENXIO ;
2006-02-08 08:42:51 +03:00
max = kzalloc ( sizeof ( struct wf_6690_sensor ) , GFP_KERNEL ) ;
if ( max = = NULL ) {
2009-06-15 20:01:51 +04:00
printk ( KERN_ERR " windfarm: Couldn't create MAX6690 sensor: "
" no memory \n " ) ;
return - ENOMEM ;
}
max - > i2c = client ;
2013-11-12 23:07:14 +04:00
max - > sens . name = name ;
2009-06-15 20:01:51 +04:00
max - > sens . ops = & wf_max6690_ops ;
i2c_set_clientdata ( client , max ) ;
rc = wf_register_sensor ( & max - > sens ) ;
2012-04-19 02:16:45 +04:00
if ( rc )
2009-06-15 20:01:51 +04:00
kfree ( max ) ;
return rc ;
}
2022-08-15 11:02:30 +03:00
static void wf_max6690_remove ( struct i2c_client * client )
2006-02-08 08:42:51 +03:00
{
2009-06-15 20:01:51 +04:00
struct wf_6690_sensor * max = i2c_get_clientdata ( client ) ;
2006-02-08 08:42:51 +03:00
2009-06-15 20:01:51 +04:00
max - > i2c = NULL ;
2006-02-08 08:42:51 +03:00
wf_unregister_sensor ( & max - > sens ) ;
}
2009-06-15 20:01:51 +04:00
static const struct i2c_device_id wf_max6690_id [ ] = {
2012-04-19 02:16:45 +04:00
{ " MAC,max6690 " , 0 } ,
2009-06-15 20:01:51 +04:00
{ }
} ;
2012-04-19 02:16:45 +04:00
MODULE_DEVICE_TABLE ( i2c , wf_max6690_id ) ;
2009-06-15 20:01:51 +04:00
2020-03-03 15:50:46 +03:00
static const struct of_device_id wf_max6690_of_id [ ] = {
{ . compatible = " max6690 " , } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , wf_max6690_of_id ) ;
2009-06-15 20:01:51 +04:00
static struct i2c_driver wf_max6690_driver = {
. driver = {
. name = " wf_max6690 " ,
2020-03-03 15:50:46 +03:00
. of_match_table = wf_max6690_of_id ,
2009-06-15 20:01:51 +04:00
} ,
. probe = wf_max6690_probe ,
. remove = wf_max6690_remove ,
. id_table = wf_max6690_id ,
} ;
2012-10-08 07:00:04 +04:00
module_i2c_driver ( wf_max6690_driver ) ;
2006-02-08 08:42:51 +03:00
MODULE_AUTHOR ( " Paul Mackerras <paulus@samba.org> " ) ;
MODULE_DESCRIPTION ( " MAX6690 sensor objects for PowerMac thermal control " ) ;
MODULE_LICENSE ( " GPL " ) ;