/* Copyright (c) 2010 Christoph Mair * Copyright (c) 2012 Bosch Sensortec GmbH * Copyright (c) 2012 Unixphere AB * * This driver supports the bmp085 and bmp18x digital barometric pressure * and temperature sensors from Bosch Sensortec. The datasheets * are available from their website: * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP180-DS000-07.pdf * * A pressure measurement is issued by reading from pressure0_input. * The return value ranges from 30000 to 110000 pascal with a resulution * of 1 pascal (0.01 millibar) which enables measurements from 9000m above * to 500m below sea level. * * The temperature can be read from temp0_input. Values range from * -400 to 850 representing the ambient temperature in degree celsius * multiplied by 10.The resolution is 0.1 celsius. * * Because ambient pressure is temperature dependent, a temperature * measurement will be executed automatically even if the user is reading * from pressure0_input. This happens if the last temperature measurement * has been executed more then one second ago. * * To decrease RMS noise from pressure measurements, the bmp085 can * autonomously calculate the average of up to eight samples. This is * set up by writing to the oversampling sysfs file. Accepted values * are 0, 1, 2 and 3. 2^x when x is the value written to this file * specifies the number of samples used to calculate the ambient pressure. * RMS noise is specified with six pascal (without averaging) and decreases * down to 3 pascal when using an oversampling setting of 3. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "bmp085.h" #include #include #include #define BMP085_CHIP_ID 0x55 #define BMP085_CALIBRATION_DATA_START 0xAA #define BMP085_CALIBRATION_DATA_LENGTH 11 /* 16 bit values */ #define BMP085_CHIP_ID_REG 0xD0 #define BMP085_CTRL_REG 0xF4 #define BMP085_TEMP_MEASUREMENT 0x2E #define BMP085_PRESSURE_MEASUREMENT 0x34 #define BMP085_CONVERSION_REGISTER_MSB 0xF6 #define BMP085_CONVERSION_REGISTER_LSB 0xF7 #define BMP085_CONVERSION_REGISTER_XLSB 0xF8 #define BMP085_TEMP_CONVERSION_TIME 5 struct bmp085_calibration_data { s16 AC1, AC2, AC3; u16 AC4, AC5, AC6; s16 B1, B2; s16 MB, MC, MD; }; struct bmp085_data { struct device *dev; struct regmap *regmap; struct mutex lock; struct bmp085_calibration_data calibration; u8 oversampling_setting; u32 raw_temperature; u32 raw_pressure; u32 temp_measurement_period; unsigned long last_temp_measurement; u8 chip_id; s32 b6; /* calculated temperature correction coefficient */ int irq; struct completion done; }; static irqreturn_t bmp085_eoc_isr(int irq, void *devid) { struct bmp085_data *data = devid; complete(&data->done); return IRQ_HANDLED; } static s32 bmp085_read_calibration_data(struct bmp085_data *data) { u16 tmp[BMP085_CALIBRATION_DATA_LENGTH]; struct bmp085_calibration_data *cali = &(data->calibration); s32 status = regmap_bulk_read(data->regmap, BMP085_CALIBRATION_DATA_START, (u8 *)tmp, (BMP085_CALIBRATION_DATA_LENGTH << 1)); if (status < 0) return status; cali->AC1 = be16_to_cpu(tmp[0]); cali->AC2 = be16_to_cpu(tmp[1]); cali->AC3 = be16_to_cpu(tmp[2]); cali->AC4 = be16_to_cpu(tmp[3]); cali->AC5 = be16_to_cpu(tmp[4]); cali->AC6 = be16_to_cpu(tmp[5]); cali->B1 = be16_to_cpu(tmp[6]); cali->B2 = be16_to_cpu(tmp[7]); cali->MB = be16_to_cpu(tmp[8]); cali->MC = be16_to_cpu(tmp[9]); cali->MD = be16_to_cpu(tmp[10]); return 0; } static s32 bmp085_update_raw_temperature(struct bmp085_data *data) { u16 tmp; s32 status; mutex_lock(&data->lock); init_completion(&data->done); status = regmap_write(data->regmap, BMP085_CTRL_REG, BMP085_TEMP_MEASUREMENT); if (status < 0) { dev_err(data->dev, "Error while requesting temperature measurement.\n"); goto exit; } wait_for_completion_timeout(&data->done, 1 + msecs_to_jiffies( BMP085_TEMP_CONVERSION_TIME)); status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB, &tmp, sizeof(tmp)); if (status < 0) { dev_err(data->dev, "Error while reading temperature measurement result\n"); goto exit; } data->raw_temperature = be16_to_cpu(tmp); data->last_temp_measurement = jiffies; status = 0; /* everything ok, return 0 */ exit: mutex_unlock(&data->lock); return status; } static s32 bmp085_update_raw_pressure(struct bmp085_data *data) { u32 tmp = 0; s32 status; mutex_lock(&data->lock); init_completion(&data->done); status = regmap_write(data->regmap, BMP085_CTRL_REG, BMP085_PRESSURE_MEASUREMENT + (data->oversampling_setting << 6)); if (status < 0) { dev_err(data->dev, "Error while requesting pressure measurement.\n"); goto exit; } /* wait for the end of conversion */ wait_for_completion_timeout(&data->done, 1 + msecs_to_jiffies( 2+(3 << data->oversampling_setting))); /* copy data into a u32 (4 bytes), but skip the first byte. */ status = regmap_bulk_read(data->regmap, BMP085_CONVERSION_REGISTER_MSB, ((u8 *)&tmp)+1, 3); if (status < 0) { dev_err(data->dev, "Error while reading pressure measurement results\n"); goto exit; } data->raw_pressure = be32_to_cpu((tmp)); data->raw_pressure >>= (8-data->oversampling_setting); status = 0; /* everything ok, return 0 */ exit: mutex_unlock(&data->lock); return status; } /* * This function starts the temperature measurement and returns the value * in tenth of a degree celsius. */ static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature) { struct bmp085_calibration_data *cali = &data->calibration; long x1, x2; int status; status = bmp085_update_raw_temperature(data); if (status < 0) goto exit; x1 = ((data->raw_temperature - cali->AC6) * cali->AC5) >> 15; x2 = (cali->MC << 11) / (x1 + cali->MD); data->b6 = x1 + x2 - 4000; /* if NULL
/*
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * EXYNOS - CPUFreq support
 *
 * 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.
*/

enum cpufreq_level_index {
	L0, L1, L2, L3, L4,
	L5, L6, L7, L8, L9,
	L10, L11, L12, L13, L14,
	L15, L16, L17, L18, L19,
	L20,
};

enum exynos_soc_type {
	EXYNOS_SOC_4210,
	EXYNOS_SOC_4212,
	EXYNOS_SOC_4412