/*
* OMAP4 Bandgap temperature sensor driver
*
* Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
* Author: J Keerthy <j-keerthy@ti.com>
* Author: Moiz Sonasath <m-sonasath@ti.com>
* Couple of fixes, DT and MFD adaptation:
* Eduardo Valentin <eduardo.valentin@ti.com>
*
* 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.
*
* 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.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
*/
#include <linux/module.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/reboot.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/io.h>
#include "omap-bandgap.h"
static u32 omap_bandgap_readl(struct omap_bandgap *bg_ptr, u32 reg)
{
return readl(bg_ptr->base + reg);
}
static void omap_bandgap_writel(struct omap_bandgap *bg_ptr, u32 val, u32 reg)
{
writel(val, bg_ptr->base + reg);
}
static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on)
{
struct temp_sensor_registers *tsr;
int i;
u32 ctrl;
if (!OMAP_BANDGAP_HAS(bg_ptr, POWER_SWITCH))
return 0;
for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
tsr = bg_ptr->conf->sensors[i].registers;
ctrl = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
ctrl &= ~tsr->bgap_tempsoff_mask;
/* active on 0 */
ctrl |= !on << __ffs(tsr->bgap_tempsoff_mask);
/* write BGAP_TEMPSOFF should be reset to 0 */
omap_bandgap_writel(bg_ptr, ctrl, tsr->temp_sensor_ctrl);
}
return 0;
}
/* This is the Talert handler. Call it only if HAS(TALERT) is set */
static irqreturn_t talert_irq_handler(int irq, void *data)
{
struct omap_bandgap *bg_ptr = data;
struct temp_sensor_registers *tsr;
u32 t_hot = 0, t_cold = 0, temp, ctrl;
int i;
bg_ptr = data;
/* Read the status of t_hot */
for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
tsr = bg_ptr->conf->sensors[i].registers;
t_hot = omap_bandgap_readl(bg_ptr, tsr->bgap_status);
t_hot &= tsr->status_hot_mask;
/* Read the status of t_cold */
t_cold = omap_bandgap_readl(bg_ptr, tsr->bgap_status);
t_cold &= tsr->status_cold_mask;
if (!t_cold && !t_hot)
continue;
ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
/*
* One TALERT interrupt: Two sources
* If the interrupt is due to t_hot then mask t_hot and
* and unmask t_cold else mask t_cold and unmask t_hot
*/
if (t_hot) {
ctrl &= ~tsr->mask_hot_mask;
ctrl |= tsr->mask_cold_mask;
} else if (t_cold) {
ctrl &=