/* * Copyright (C) 2010-2015 Freescale Semiconductor, Inc. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* * max17135.c * * Based on the MAX1619 driver. * Copyright (C) 2003-2004 Alexey Fisher * Jean Delvare * * The MAX17135 is a sensor chip made by Maxim. * It reports up to two temperatures (its own plus up to * one external one). */ #include #include #include #include #include #include #include #include #include #include /* * Conversions */ static int temp_from_reg(int val) { return val >> 8; } /* * Functions declaration */ static int max17135_sensor_probe(struct platform_device *pdev); static int max17135_sensor_remove(struct platform_device *pdev); static const struct platform_device_id max17135_sns_id[] = { { "max17135-sns", 0}, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(platform, max17135_sns_id); /* * Driver data (common to all clients) */ static struct platform_driver max17135_sensor_driver = { .probe = max17135_sensor_probe, .remove = max17135_sensor_remove, .id_table = max17135_sns_id, .driver = { .name = "max17135_sensor", }, }; /* * Client data (each client gets its own) */ struct max17135_data { struct device *hwmon_dev; }; /* * Sysfs stuff */ static ssize_t show_temp_input1(struct device *dev, struct device_attribute *attr, char *buf) { unsigned int reg_val; max17135_reg_read(REG_MAX17135_INT_TEMP, ®_val); return snprintf(buf, PAGE_SIZE, "%d\n", temp_from_reg(reg_val)); } static ssize_t show_temp_input2(struct device *dev, struct device_attribute *attr, char *buf) { unsigned int reg_val; max17135_reg_read(REG_MAX17135_EXT_TEMP, ®_val); return snprintf(buf, PAGE_SIZE, "%d\n", temp_from_reg(reg_val)); } static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input1, NULL); static DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_input2, NULL); static struct attribute *max17135_attributes[] = { &dev_attr_temp1_input.attr, &dev_attr_temp2_input.attr, NULL }; static const struct attribute_group max17135_group = { .attrs = max17135_attributes, }; /* * Real code */ static int max17135_sensor_probe(struct platform_device *pdev) { struct max17135_data *data; int err; data = kzalloc(sizeof(struct max17135_data), GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit; } /* Register sysfs hooks */ err = sysfs_create_group(&pdev->dev.kobj, &max17135_group); if (err) goto exit_free; data->hwmon_dev = hwmon_device_register(&pdev->dev); if (IS_ERR(data->hwmon_dev)) { err = PTR_ERR(data->hwmon_dev); goto exit_remove_files; } platform_set_drvdata(pdev, data); return 0; exit_remove_files: sysfs_remove_group(&pdev->dev.kobj, &max17135_group); exit_free: kfree(data); exit: return err; } static int max17135_sensor_remove(struct platform_device *pdev) { struct max17135_data *data = platform_get_drvdata(pdev); hwmon_device_unregister(data->hwmon_dev); sysfs_remove_group(&pdev->dev.kobj, &max17135_group); kfree(data); return 0; } static int __init sensors_max17135_init(void) { return platform_driver_register(&max17135_sensor_driver); } module_init(sensors_max17135_init); static void __exit sensors_max17135_exit(void) { platform_driver_unregister(&max17135_sensor_driver); } module_exit(sensors_max17135_exit); MODULE_DESCRIPTION("MAX17135 sensor driver"); MODULE_LICENSE("GPL");