aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/max8893.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/max8893.c')
-rw-r--r--drivers/misc/max8893.c160
1 files changed, 160 insertions, 0 deletions
diff --git a/drivers/misc/max8893.c b/drivers/misc/max8893.c
new file mode 100644
index 0000000..9a3836a
--- /dev/null
+++ b/drivers/misc/max8893.c
@@ -0,0 +1,160 @@
+/*
+*
+*Minimalistic MAX8893 PMIC driver for CMC732 WiMAX chipset
+*
+*Use retrys when bus is shared or problematic.
+*
+*Functions not exported are made static
+*
+*In this driver, BUCK is referred as LDO number "-1"
+*/
+
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/wimax/samsung/max8893.h>
+
+/*#define WIMAX_DEBUG*/
+
+
+static struct i2c_client *max8893_client;
+
+
+
+static int max8893_set_ldo(int ldo, int enable)
+{
+ int temp;
+ temp = i2c_smbus_read_byte_data(max8893_client, MAX8893_REG_ONOFF);
+ if (temp < 0)
+ return temp;
+ temp = enable ? (temp|ENABLE_LDO(ldo)) : (temp&DISABLE_LDO(ldo));
+ return i2c_smbus_write_byte_data(max8893_client,
+ MAX8893_REG_ONOFF, (unsigned char)temp);
+
+}
+
+#ifdef WIMAX_DEBUG
+
+static int max8893_get_ldo(int ldo)
+{
+ int temp;
+ temp = i2c_smbus_read_byte_data(max8893_client, MAX8893_REG_ONOFF);
+ if (temp < 0)
+ return temp;
+ return (temp&ENABLE_LDO(ldo)) ? 1 : 0;
+}
+
+static int max8893_get_voltage(int ldo)
+{
+ int voltage;
+ voltage = i2c_smbus_read_byte_data(max8893_client,
+ MAX8893_REG_LDO(ldo));
+ return voltage ;
+
+}
+
+#endif
+
+static int max8893_set_voltage(int ldo, int mv)
+{
+ int temp;
+ if (mv > MAX_VOLTAGE(ldo))
+ return -22;
+ temp = MIN_VOLTAGE(ldo);
+ if (mv < temp)
+ return -22;
+ temp = (mv - temp)/100;
+ return i2c_smbus_write_byte_data(max8893_client,
+ MAX8893_REG_LDO(ldo), (unsigned char)temp);
+}
+
+int wimax_pmic_set_voltage(void)
+{
+ int ret;
+#ifdef WIMAX_DEBUG
+ int i;
+#endif
+
+ mdelay(10);
+ ret = (
+ max8893_set_voltage(BUCK, 1200)|
+ max8893_set_voltage(LDO1, 2800)|
+ max8893_set_voltage(LDO2, 2800)|
+ max8893_set_voltage(LDO3, 3300)|
+ max8893_set_voltage(LDO4, 2900)|
+ max8893_set_voltage(LDO5, 2800)
+ );
+ if (ret)
+ printk(KERN_ERR "ERROR SETTING WIMAX PMIC POWER ret = %d\n",
+ ret);
+
+#ifdef WIMAX_DEBUG
+ max8893_set_ldo(BUCK, ON);
+ max8893_set_ldo(LDO1, ON);
+ max8893_set_ldo(LDO2, ON);
+ max8893_set_ldo(LDO3, ON);
+ max8893_set_ldo(LDO4, ON);
+ max8893_set_ldo(LDO5, ON);
+
+ for (i = 1; i < 6; i++) {
+ printk(KERN_DEBUG "[WIMAX_DEBUG] LDO%d STATE :%d\n", i,
+ max8893_get_ldo(i));
+ printk(KERN_DEBUG "[WIMAX_DEBUG] LDO%d VOLTAGE:%x\n", i,
+ max8893_get_voltage(i));
+ }
+#endif
+ return ret;
+}
+EXPORT_SYMBOL(wimax_pmic_set_voltage);
+
+static int max8893_wmx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+#ifdef WIMAX_DEBUG
+ int i;
+#endif
+ max8893_client = client;
+ return 0;
+}
+
+
+static int max8893_wmx_remove(struct i2c_client *client)
+{
+ max8893_set_ldo(BUCK, OFF);
+ max8893_set_ldo(LDO1, OFF);
+ max8893_set_ldo(LDO2, OFF);
+ max8893_set_ldo(LDO3, OFF);
+ max8893_set_ldo(LDO4, OFF);
+ max8893_set_ldo(LDO5, OFF);
+ return 0;
+}
+const struct i2c_device_id max8893_wmx_id[] = {
+ { "max8893_wmx", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, max8893_wmx_id);
+static struct i2c_driver max8893_wmx_driver = {
+ .probe = max8893_wmx_probe,
+ .remove = max8893_wmx_remove,
+ .id_table = max8893_wmx_id,
+ .driver = {
+ .name = "max8893_wmx",
+ },
+};
+static int __init max8893_wmx_pmic_init(void)
+{
+ return i2c_add_driver(&max8893_wmx_driver);
+}
+static void __exit max8893_wmx_pmic_exit(void)
+{
+ i2c_del_driver(&max8893_wmx_driver);
+}
+subsys_initcall(max8893_wmx_pmic_init);
+module_exit(max8893_wmx_pmic_exit);
+MODULE_DESCRIPTION("MAXIM 8893 PMIC driver for WiMAX");
+MODULE_AUTHOR("SAMSUNG ELECTRONICS");
+MODULE_LICENSE("GPL");