blob: 22a53b2577de1d4d14ea7a75633d6ac12c178027 [file] [log] [blame]
/*
* Copyright (C) 2016 Google, Inc.
*
* Author: Trevor Bunker <trevorbunker@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include "bcm15602-regulator.h"
#define DRIVER_NAME "bcm15602-thermal"
#define BCM15602_THERM_NUM_TRIPS 0
#define BCM15602_THERM_TRIPS_MASK ((1 << BCM15602_THERM_NUM_TRIPS) - 1)
struct bcm15602_thermal {
struct bcm15602_chip *bcm15602;
struct thermal_zone_device *tz_dev;
};
static int bcm15602_thermal_get_temp(struct thermal_zone_device *tz_dev,
int *temp)
{
struct bcm15602_thermal *bcm15602_thermal = tz_dev->devdata;
struct bcm15602_chip *bcm15602 = bcm15602_thermal->bcm15602;
u16 chan_data = 0;
int ret;
ret = bcm15602_read_adc_chan(bcm15602, BCM15602_ADC_PTAT, &chan_data);
if (ret)
return ret;
*temp = PTAT_CODE_TO_TEMP(chan_data);
return 0;
}
static int bcm15602_thermal_get_mode(struct thermal_zone_device *tz_dev,
enum thermal_device_mode *mode)
{
*mode = THERMAL_DEVICE_ENABLED;
return 0;
}
static struct thermal_zone_device_ops bcm15602_thermal_ops = {
.get_temp = bcm15602_thermal_get_temp,
.get_mode = bcm15602_thermal_get_mode,
};
static int bcm15602_thermal_probe(struct platform_device *pdev)
{
struct bcm15602_chip *bcm15602 = dev_get_drvdata(pdev->dev.parent);
struct bcm15602_thermal *bcm15602_thermal;
char tz_name[] = "bcm15602_tz";
bcm15602_thermal = devm_kzalloc(&pdev->dev,
sizeof(struct bcm15602_thermal),
GFP_KERNEL);
if (!bcm15602_thermal)
return -ENOMEM;
bcm15602_thermal->bcm15602 = bcm15602;
/* register the thermal zone device */
bcm15602_thermal->tz_dev =
thermal_zone_device_register(tz_name, BCM15602_THERM_NUM_TRIPS,
BCM15602_THERM_TRIPS_MASK,
bcm15602_thermal,
&bcm15602_thermal_ops,
NULL, 0, 0);
if (IS_ERR(bcm15602_thermal->tz_dev)) {
dev_err(&pdev->dev, "%s: failed to register thermal zone device (%ld)\n",
__func__, PTR_ERR(bcm15602_thermal->tz_dev));
return -ENODEV;
}
platform_set_drvdata(pdev, bcm15602_thermal);
return 0;
}
static int bcm15602_thermal_remove(struct platform_device *pdev)
{
struct bcm15602_thermal *bcm15602_thermal = platform_get_drvdata(pdev);
if (bcm15602_thermal->tz_dev)
thermal_zone_device_unregister(bcm15602_thermal->tz_dev);
return 0;
}
static const struct of_device_id bcm15602_thermal_of_match[] = {
{ .compatible = "brcm,bcm15602-thermal", },
{ }
};
MODULE_DEVICE_TABLE(of, bcm15602_thermal_of_match);
static struct platform_driver bcm15602_thermal_driver = {
.probe = bcm15602_thermal_probe,
.remove = bcm15602_thermal_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = bcm15602_thermal_of_match,
},
};
module_platform_driver(bcm15602_thermal_driver);
MODULE_AUTHOR("Trevor Bunker <trevorbunker@google.com>");
MODULE_DESCRIPTION("BCM15602 Thermal Sensor Driver");
MODULE_LICENSE("GPL");