Not a member of Pastebin yet?
                        Sign Up,
                        it unlocks many cool features!                    
                - /*
 - * i.mx233 external temperature sensing with a diode
 - *
 - * 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.
 - */
 - #include <linux/init.h>
 - #include <linux/module.h>
 - #include <linux/kernel.h>
 - #include <linux/device.h>
 - #include <linux/err.h>
 - #include <linux/sysfs.h>
 - #include <linux/hwmon.h>
 - #include <linux/mutex.h>
 - #include <linux/io.h>
 - #include <linux/platform_device.h>
 - #include <asm/processor.h> /* cpu_relax */
 - #include <mach/hardware.h>
 - #include <mach/lradc.h>
 - #include <mach/regs-power.h>
 - #include <mach/regs-lradc.h>
 - #define REGS_LRADC_BASE IO_ADDRESS(LRADC_PHYS_ADDR)
 - #define THERM_CHANNEL 0
 - #define LRADC_IRQ_MASK (1 << THERM_CHANNEL)
 - #define KELVIN_TO_CELSIUS_CONST (273*1000)
 - struct mxs_therm {
 - struct device *hwmon_dev;
 - struct mutex lock;
 - };
 - static uint32_t get_codevalue(void)
 - {
 - int i;
 - uint32_t codevalue;
 - codevalue = 0;
 - for (i = 0; i < 8; i++) {
 - __raw_writel(BF_LRADC_CTRL0_SCHEDULE(1 << THERM_CHANNEL),
 - REGS_LRADC_BASE + HW_LRADC_CTRL0_SET);
 - /* Wait for conversion complete*/
 - while (!(__raw_readl(REGS_LRADC_BASE + HW_LRADC_CTRL1)
 - & LRADC_IRQ_MASK))
 - cpu_relax();
 - /* Clear the interrupt flag */
 - __raw_writel(LRADC_IRQ_MASK,
 - REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR);
 - /* read temperature value and clr lradc */
 - codevalue += __raw_readl(REGS_LRADC_BASE +
 - HW_LRADC_CHn(THERM_CHANNEL)) & BM_LRADC_CHn_VALUE;
 - __raw_writel(BM_LRADC_CHn_VALUE,
 - REGS_LRADC_BASE + HW_LRADC_CHn_CLR(THERM_CHANNEL));
 - }
 - return (codevalue >> 3);
 - }
 - /*
 - * Use the the lradc0 channel
 - *
 - */
 - static int measure_temperature(void)
 - {
 - int code1, code2, ret_temp, i;
 - /* Enable temperature sensor current source */
 - __raw_writel(BM_LRADC_CTRL2_TEMP_SENSOR_IENABLE0,
 - REGS_LRADC_BASE + HW_LRADC_CTRL2_SET);
 - /* mux to the lradc 0th temp channe0 */
 - __raw_writel((0xF << (4 * THERM_CHANNEL)),
 - REGS_LRADC_BASE + HW_LRADC_CTRL4_CLR);
 - /* Clear the interrupt flag */
 - __raw_writel(LRADC_IRQ_MASK,
 - REGS_LRADC_BASE + HW_LRADC_CTRL1_CLR);
 - ret_temp = 0;
 - for (i = 0; i < 8; i++) {
 - __raw_writel(BM_LRADC_CTRL2_TEMP_ISRC0,
 - REGS_LRADC_BASE + HW_LRADC_CTRL2_CLR);
 - __raw_writel(BF_LRADC_CTRL2_TEMP_ISRC0(BV_LRADC_CTRL2_TEMP_ISRC0__300),
 - REGS_LRADC_BASE + HW_LRADC_CTRL2_SET);
 - code1 = get_codevalue();
 - __raw_writel(BM_LRADC_CTRL2_TEMP_ISRC0,
 - REGS_LRADC_BASE + HW_LRADC_CTRL2_CLR);
 - __raw_writel(BF_LRADC_CTRL2_TEMP_ISRC0(BV_LRADC_CTRL2_TEMP_ISRC0__20),
 - REGS_LRADC_BASE + HW_LRADC_CTRL2_SET);
 - code2 = get_codevalue();
 - /* degrees Kelvin = (Codemax – Codemin) * 1.104 */
 - ret_temp += (code1 - code2) * 1104;
 - }
 - /* Disable temperature sensor current source */
 - __raw_writel(BM_LRADC_CTRL2_TEMP_SENSOR_IENABLE0,
 - REGS_LRADC_BASE + HW_LRADC_CTRL2_CLR);
 - return ((ret_temp >> 3) - KELVIN_TO_CELSIUS_CONST);
 - }
 - static ssize_t mxs_therm_sense_temp(struct device *dev,
 - struct device_attribute *attr, char *buf)
 - {
 - struct mxs_therm *mxs_therm_data = dev_get_drvdata(dev);
 - int status;
 - int val;
 - if (mutex_lock_interruptible(&mxs_therm_data->lock))
 - return -ERESTARTSYS;
 - val = measure_temperature();
 - status = sprintf(buf, "%d\n", val);
 - mutex_unlock(&mxs_therm_data->lock);
 - return status;
 - }
 - static DEVICE_ATTR(temp1_input, S_IRUGO, mxs_therm_sense_temp, NULL);
 - static ssize_t mxs_therm_show_name(struct device *dev, struct device_attribute
 - *devattr, char *buf)
 - {
 - return sprintf(buf, "%s\n", "mxs_therm");
 - }
 - static DEVICE_ATTR(name, S_IRUGO, mxs_therm_show_name, NULL);
 - static int __init mxs_therm_probe(struct platform_device *pdev)
 - {
 - struct mxs_therm *mxs_therm_data;
 - int status;
 - mxs_therm_data = kzalloc(sizeof *mxs_therm_data, GFP_KERNEL);
 - if (!mxs_therm_data)
 - return -ENOMEM;
 - mutex_init(&mxs_therm_data->lock);
 - /* sysfs hook */
 - mxs_therm_data->hwmon_dev = hwmon_device_register(&pdev->dev);
 - if (IS_ERR(mxs_therm_data->hwmon_dev)) {
 - dev_dbg(&pdev->dev, "hwmon_device_register failed.\n");
 - status = PTR_ERR(mxs_therm_data->hwmon_dev);
 - goto out_dev_reg_failed;
 - }
 - platform_set_drvdata(pdev, mxs_therm_data);
 - if ((status = device_create_file(&pdev->dev, &dev_attr_temp1_input))
 - || (status = device_create_file(&pdev->dev, &dev_attr_name))) {
 - dev_dbg(&pdev->dev, "device_create_file failure.\n");
 - goto out_dev_create_file_failed;
 - }
 - return 0;
 - out_dev_create_file_failed:
 - device_remove_file(&pdev->dev, &dev_attr_temp1_input);
 - hwmon_device_unregister(mxs_therm_data->hwmon_dev);
 - out_dev_reg_failed:
 - platform_set_drvdata(pdev, NULL);
 - kfree(mxs_therm_data);
 - return status;
 - }
 - static int mxs_therm_remove(struct platform_device *pdev)
 - {
 - struct mxs_therm *mxs_therm_data = platform_get_drvdata(pdev);
 - hwmon_device_unregister(mxs_therm_data->hwmon_dev);
 - device_remove_file(&pdev->dev, &dev_attr_temp1_input);
 - device_remove_file(&pdev->dev, &dev_attr_name);
 - platform_set_drvdata(pdev, NULL);
 - kfree(mxs_therm_data);
 - return 0;
 - }
 - static struct platform_driver mxs_therm_driver = {
 - .driver = {
 - .name = "mxs_therm",
 - },
 - .probe = mxs_therm_probe,
 - .remove = mxs_therm_remove,
 - };
 - static struct platform_device *mxs_therm_device;
 - static int __init mxs_therm_init(void)
 - {
 - int ret = 0;
 - ret = platform_driver_register(&mxs_therm_driver);
 - if (!ret) {
 - mxs_therm_device = platform_device_alloc("mxs_therm", 0);
 - if (mxs_therm_device)
 - ret = platform_device_add(mxs_therm_device);
 - else
 - ret = -ENOMEM;
 - if (ret) {
 - platform_device_put(mxs_therm_device);
 - platform_driver_unregister(&mxs_therm_driver);
 - }
 - }
 - return ret;
 - }
 - static void __exit mxs_therm_exit(void)
 - {
 - platform_device_unregister(mxs_therm_device);
 - platform_driver_unregister(&mxs_therm_driver);
 - }
 - module_init(mxs_therm_init);
 - module_exit(mxs_therm_exit);
 - MODULE_AUTHOR("starterkit");
 - MODULE_DESCRIPTION("External temperature sensing with a diode");
 - MODULE_LICENSE("GPL");
 
Advertisement
 
                    Add Comment                
                
                        Please, Sign In to add comment