/* * 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 * */ /*! * @file pmic/core/max17135.c * @brief This file contains MAX17135 specific PMIC code. This implementaion * may differ for each PMIC chip. * * @ingroup PMIC_CORE */ /* * Includes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int max17135_detect(struct i2c_client *client, struct i2c_board_info *info); struct i2c_client *max17135_client; static struct regulator *gpio_regulator; static struct mfd_cell max17135_devs[] = { { .name = "max17135-pmic", }, { .name = "max17135-sns", }, }; static const unsigned short normal_i2c[] = {0x48, I2C_CLIENT_END}; int max17135_reg_read(int reg_num, unsigned int *reg_val) { int result; if (max17135_client == NULL) return PMIC_ERROR; if ((reg_num == REG_MAX17135_EXT_TEMP) || (reg_num == REG_MAX17135_INT_TEMP)) { result = i2c_smbus_read_word_data(max17135_client, reg_num); if (result < 0) { dev_err(&max17135_client->dev, "Unable to read MAX17135 register via I2C\n"); return PMIC_ERROR; } /* Swap bytes for dword read */ result = (result >> 8) | ((result & 0xFF) << 8); } else { result = i2c_smbus_read_byte_data(max17135_client, reg_num); if (result < 0) { dev_err(&max17135_client->dev, "Unable to read MAX17135 register via I2C\n"); return PMIC_ERROR; } } *reg_val = result; return PMIC_SUCCESS; } int max17135_reg_write(int reg_num, const unsigned int reg_val) { int result; if (max17135_client == NULL) return PMIC_ERROR; result = i2c_smbus_write_byte_data(max17135_client, reg_num, reg_val); if (result < 0) { dev_err(&max17135_client->dev, "Unable to write MAX17135 register via I2C\n"); return PMIC_ERROR; } return PMIC_SUCCESS; } #ifdef CONFIG_OF static struct max17135_platform_data *max17135_i2c_parse_dt_pdata( struct device *dev) { struct max17135_platform_data *pdata; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(dev, "could not allocate memory for pdata\n"); return ERR_PTR(-ENOMEM); } return pdata; } #else static struct max17135_platform_data *max17135_i2c_parse_dt_pdata( struct device *dev) { return NULL; } #endif /* !CONFIG_OF */ static int max17135_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max17135 *max17135; struct max17135_platform_data *pdata = client->dev.platform_data; struct device_node *np = client->dev.of_node; int ret = 0; if (!np) return -ENODEV; gpio_regulator = devm_regulator_get(&client->dev, "SENSOR"); if (!IS_ERR(gpio_regulator)) { ret = regulator_enable(gpio_regulator); if (ret) { dev_err(&client->dev, "gpio set voltage error\n"); return ret; } } /* Create the PMIC data structure */ max17135 = kzalloc(sizeof(struct max17135), GFP_KERNEL); if (max17135 == NULL) return -ENOMEM; /* Initialize the PMIC data structure */ i2c_set_clientdata(client, max17135); max17135->dev = &client->dev; max17135->i2c_client = client; max17135_client = client; ret = max17135_detect(client, NULL); if (ret) goto err1; mfd_add_devices(max17135->dev, -1, max17135_devs, ARRAY_SIZE(max17135_devs), NULL, 0, NULL); if (max17135->dev->of_node) { pdata = max17135_i2c_parse_dt_pdata(max17135->dev); if (IS_ERR(pdata)) { ret = PTR_ERR(pdata); goto err2; } } max17135->pdata = pdata; dev_info(&client->dev, "PMIC MAX17135 for eInk display\n"); return ret; err2: mfd_remove_devices(max17135->dev); err1: kfree(max17135); return ret; } static int max17135_remove(struct i2c_client *i2c) { struct max17135 *max17135 = i2c_get_clientdata(i2c); mfd_remove_devices(max17135->dev); return 0; } /* Return 0 if detection is successful, -ENODEV otherwise */ static int max17135_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; u8 chip_rev, chip_id; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; /* detection */ if (i2c_smbus_read_byte_data(client, REG_MAX17135_PRODUCT_REV) != 0) { dev_err(&adapter->dev, "Max17135 PMIC not found!\n"); return -ENODEV; } /* identification */ chip_rev = i2c_smbus_read_byte_data(client, REG_MAX17135_PRODUCT_REV); chip_id = i2c_smbus_read_byte_data(client, REG_MAX17135_PRODUCT_ID); if (chip_rev != 0x00 || chip_id != 0x4D) { /* identification failed */ dev_info(&adapter->dev, "Unsupported chip (man_id=0x%02X, " "chip_id=0x%02X).\n", chip_rev, chip_id); return -ENODEV; } if (info) strlcpy(info->type, "max17135_sensor", I2C_NAME_SIZE); return 0; } static const struct i2c_device_id max17135_id[] = { { "max17135", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, max17135_id); static const struct of_device_id max17135_dt_ids[] = { { .compatible = "maxim,max17135", .data = (void *) &max17135_id[0], }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, max17135_dt_ids); static struct i2c_driver max17135_driver = { .driver = { .name = "max17135", .owner = THIS_MODULE, .of_match_table = max17135_dt_ids, }, .probe = max17135_probe, .remove = max17135_remove, .id_table = max17135_id, .detect = max17135_detect, .address_list = &normal_i2c[0], }; static int __init max17135_init(void) { return i2c_add_driver(&max17135_driver); } static void __exit max17135_exit(void) { i2c_del_driver(&max17135_driver); } /* * Module entry points */ subsys_initcall(max17135_init); module_exit(max17135_exit);