/drivers/hwmon/max8688.c
C | 158 lines | 123 code | 15 blank | 20 comment | 14 complexity | 1466a0a3dd3f601fa04e8d7b6b4df437 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* 2 * Hardware monitoring driver for Maxim MAX8688 3 * 4 * Copyright (c) 2011 Ericsson AB. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21#include <linux/kernel.h> 22#include <linux/module.h> 23#include <linux/init.h> 24#include <linux/err.h> 25#include <linux/i2c.h> 26#include "pmbus.h" 27 28#define MAX8688_MFG_STATUS 0xd8 29 30#define MAX8688_STATUS_OC_FAULT (1 << 4) 31#define MAX8688_STATUS_OV_FAULT (1 << 5) 32#define MAX8688_STATUS_OV_WARNING (1 << 8) 33#define MAX8688_STATUS_UV_FAULT (1 << 9) 34#define MAX8688_STATUS_UV_WARNING (1 << 10) 35#define MAX8688_STATUS_UC_FAULT (1 << 11) 36#define MAX8688_STATUS_OC_WARNING (1 << 12) 37#define MAX8688_STATUS_OT_FAULT (1 << 13) 38#define MAX8688_STATUS_OT_WARNING (1 << 14) 39 40static int max8688_read_byte_data(struct i2c_client *client, int page, int reg) 41{ 42 int ret = 0; 43 int mfg_status; 44 45 if (page) 46 return -EINVAL; 47 48 switch (reg) { 49 case PMBUS_STATUS_VOUT: 50 mfg_status = pmbus_read_word_data(client, 0, 51 MAX8688_MFG_STATUS); 52 if (mfg_status < 0) 53 return mfg_status; 54 if (mfg_status & MAX8688_STATUS_UV_WARNING) 55 ret |= PB_VOLTAGE_UV_WARNING; 56 if (mfg_status & MAX8688_STATUS_UV_FAULT) 57 ret |= PB_VOLTAGE_UV_FAULT; 58 if (mfg_status & MAX8688_STATUS_OV_WARNING) 59 ret |= PB_VOLTAGE_OV_WARNING; 60 if (mfg_status & MAX8688_STATUS_OV_FAULT) 61 ret |= PB_VOLTAGE_OV_FAULT; 62 break; 63 case PMBUS_STATUS_IOUT: 64 mfg_status = pmbus_read_word_data(client, 0, 65 MAX8688_MFG_STATUS); 66 if (mfg_status < 0) 67 return mfg_status; 68 if (mfg_status & MAX8688_STATUS_UC_FAULT) 69 ret |= PB_IOUT_UC_FAULT; 70 if (mfg_status & MAX8688_STATUS_OC_WARNING) 71 ret |= PB_IOUT_OC_WARNING; 72 if (mfg_status & MAX8688_STATUS_OC_FAULT) 73 ret |= PB_IOUT_OC_FAULT; 74 break; 75 case PMBUS_STATUS_TEMPERATURE: 76 mfg_status = pmbus_read_word_data(client, 0, 77 MAX8688_MFG_STATUS); 78 if (mfg_status < 0) 79 return mfg_status; 80 if (mfg_status & MAX8688_STATUS_OT_WARNING) 81 ret |= PB_TEMP_OT_WARNING; 82 if (mfg_status & MAX8688_STATUS_OT_FAULT) 83 ret |= PB_TEMP_OT_FAULT; 84 break; 85 default: 86 ret = -ENODATA; 87 break; 88 } 89 return ret; 90} 91 92static struct pmbus_driver_info max8688_info = { 93 .pages = 1, 94 .direct[PSC_VOLTAGE_IN] = true, 95 .direct[PSC_VOLTAGE_OUT] = true, 96 .direct[PSC_TEMPERATURE] = true, 97 .direct[PSC_CURRENT_OUT] = true, 98 .m[PSC_VOLTAGE_IN] = 19995, 99 .b[PSC_VOLTAGE_IN] = 0, 100 .R[PSC_VOLTAGE_IN] = -1, 101 .m[PSC_VOLTAGE_OUT] = 19995, 102 .b[PSC_VOLTAGE_OUT] = 0, 103 .R[PSC_VOLTAGE_OUT] = -1, 104 .m[PSC_CURRENT_OUT] = 23109, 105 .b[PSC_CURRENT_OUT] = 0, 106 .R[PSC_CURRENT_OUT] = -2, 107 .m[PSC_TEMPERATURE] = -7612, 108 .b[PSC_TEMPERATURE] = 335, 109 .R[PSC_TEMPERATURE] = -3, 110 .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP 111 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT 112 | PMBUS_HAVE_STATUS_TEMP, 113 .read_byte_data = max8688_read_byte_data, 114}; 115 116static int max8688_probe(struct i2c_client *client, 117 const struct i2c_device_id *id) 118{ 119 return pmbus_do_probe(client, id, &max8688_info); 120} 121 122static int max8688_remove(struct i2c_client *client) 123{ 124 return pmbus_do_remove(client); 125} 126 127static const struct i2c_device_id max8688_id[] = { 128 {"max8688", 0}, 129 { } 130}; 131 132MODULE_DEVICE_TABLE(i2c, max8688_id); 133 134/* This is the driver that will be inserted */ 135static struct i2c_driver max8688_driver = { 136 .driver = { 137 .name = "max8688", 138 }, 139 .probe = max8688_probe, 140 .remove = max8688_remove, 141 .id_table = max8688_id, 142}; 143 144static int __init max8688_init(void) 145{ 146 return i2c_add_driver(&max8688_driver); 147} 148 149static void __exit max8688_exit(void) 150{ 151 i2c_del_driver(&max8688_driver); 152} 153 154MODULE_AUTHOR("Guenter Roeck"); 155MODULE_DESCRIPTION("PMBus driver for Maxim MAX8688"); 156MODULE_LICENSE("GPL"); 157module_init(max8688_init); 158module_exit(max8688_exit);