Commit a31b83fc authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

PCA9571 controlling

parent 1809d055
...@@ -39,10 +39,10 @@ ...@@ -39,10 +39,10 @@
#define SYSFS_WRITEONLY 0222 #define SYSFS_WRITEONLY 0222
#define GPIO_CHIP1_ADDR 0x20 #define GPIO_CHIP1_ADDR 0x20
#define GPIO_CHIP2_ADDR 0x21 #define GPIO_CHIP2_ADDR 0x21
#define GPIO_10389_U4_ADDR 0x25 #define GPIO_10389_U4_ADDR 0x25
#define LTC3589_ADDR 0x34 #define LTC3589_ADDR 0x34
/* TODO: set resistors in device tree to accommodate different revisions ( elphel393_pwr,vp15_r1 = <357000>)*/ /* TODO: set resistors in device tree to accommodate different revisions ( elphel393_pwr,vp15_r1 = <357000>)*/
#define VP15_R1 357000 #define VP15_R1 357000
...@@ -73,7 +73,7 @@ struct pwr_gpio_t { ...@@ -73,7 +73,7 @@ struct pwr_gpio_t {
struct elphel393_pwr_data_t { struct elphel393_pwr_data_t {
int chip_i2c_addr[4]; int chip_i2c_addr[4];
struct device * ltc3489_dev; struct device * ltc3489_dev;
struct pwr_gpio_t pwr_gpio [16]; struct pwr_gpio_t pwr_gpio [24];
int simulate; /* do not perform actual i2c writes */ int simulate; /* do not perform actual i2c writes */
struct mutex lock; struct mutex lock;
int pgoot_timeout; int pgoot_timeout;
...@@ -204,7 +204,7 @@ static struct voltage_reg_t voltage_reg[]={ ...@@ -204,7 +204,7 @@ static struct voltage_reg_t voltage_reg[]={
}, },
}; };
static struct pwr_gpio_t pwr_gpio[16]={ static struct pwr_gpio_t pwr_gpio[24]={
/* 0x20: */ /* 0x20: */
{"PWR_MGB1", 0, 0, 0}, /* 1.8V margining magnitude (0 - 5%, 1 - 10%, float - 15%) */ {"PWR_MGB1", 0, 0, 0}, /* 1.8V margining magnitude (0 - 5%, 1 - 10%, float - 15%) */
{"PWR_MG1", 1, 0, 0}, /* 1.8V margining enable 0 - negative margining, 1 - positive margining, float - no margining */ {"PWR_MG1", 1, 0, 0}, /* 1.8V margining enable 0 - negative margining, 1 - positive margining, float - no margining */
...@@ -262,9 +262,12 @@ static ssize_t pgood_show(struct device *dev, struct device_attribute *attr, cha ...@@ -262,9 +262,12 @@ static ssize_t pgood_show(struct device *dev, struct device_attribute *attr, cha
static ssize_t pbad_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t pbad_show(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t enable_por_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t enable_por_show(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t enable_por_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); static ssize_t enable_por_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
static ssize_t gpio_10389_get(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t gpio_10389_set(struct device *dev, struct device_attribute *attr, char *buf, size_t count);
static ssize_t gpio_poweroff(struct device *dev, struct device_attribute *attr, char *buf, size_t count);
static int por_ctrl(struct device *dev, int disable_por);
static int gpio_shutdown(struct device *dev); static int gpio_shutdown(struct device *dev);
static int por_ctrl(struct device *dev, int disable_por);
static int get_and_disable_por(struct device *dev, int chn_bits, int * old_dis_por); static int get_and_disable_por(struct device *dev, int chn_bits, int * old_dis_por);
static int reenable_por(struct device *dev); static int reenable_por(struct device *dev);
static int wait_all_pgood(struct device *dev); static int wait_all_pgood(struct device *dev);
...@@ -312,8 +315,8 @@ static DEVICE_ATTR(channels_dis, SYSFS_PERMISSIONS, channels ...@@ -312,8 +315,8 @@ static DEVICE_ATTR(channels_dis, SYSFS_PERMISSIONS, channels
static DEVICE_ATTR(power_good, SYSFS_PERMISSIONS & SYSFS_READONLY, pgood_show, NULL); static DEVICE_ATTR(power_good, SYSFS_PERMISSIONS & SYSFS_READONLY, pgood_show, NULL);
static DEVICE_ATTR(power_bad, SYSFS_PERMISSIONS & SYSFS_READONLY, pbad_show, NULL); static DEVICE_ATTR(power_bad, SYSFS_PERMISSIONS & SYSFS_READONLY, pbad_show, NULL);
static DEVICE_ATTR(enable_por, SYSFS_PERMISSIONS, enable_por_show, enable_por_store); static DEVICE_ATTR(enable_por, SYSFS_PERMISSIONS, enable_por_show, enable_por_store);
static DEVICE_ATTR(power_off, SYSFS_PERMISSIONS , NULL, gpio_shutdown); static DEVICE_ATTR(power_off, SYSFS_PERMISSIONS , NULL, gpio_poweroff);
static DEVICE_ATTR(gpio_10389, SYSFS_PERMISSIONS, gpio_10389_get, gpio_10389_set);
static struct attribute *root_dev_attrs[] = { static struct attribute *root_dev_attrs[] = {
&dev_attr_simulate.attr, &dev_attr_simulate.attr,
...@@ -325,6 +328,7 @@ static struct attribute *root_dev_attrs[] = { ...@@ -325,6 +328,7 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_power_bad.attr, &dev_attr_power_bad.attr,
&dev_attr_enable_por.attr, &dev_attr_enable_por.attr,
&dev_attr_power_off.attr, &dev_attr_power_off.attr,
&dev_attr_gpio_10389.attr,
NULL NULL
}; };
static const struct attribute_group dev_attr_root_group = { static const struct attribute_group dev_attr_root_group = {
...@@ -589,6 +593,54 @@ static ssize_t enable_por_store(struct device *dev, struct device_attribute *att ...@@ -589,6 +593,54 @@ static ssize_t enable_por_store(struct device *dev, struct device_attribute *att
return count; return count;
} }
int gpio_10389_ctrl(struct device *dev, int value){
int i, res;
int val = 0;
//lock here
for(i=16;i<20;i++){
if ((value>>(i-8))&0x1){
val = (value>>(i-16))&0x1;
res = gpio_conf_by_index(dev, i, 1, ~val);
if (res<0) return res;
res = gpio_conf_by_index(dev, i, 1, val);
if (res<0) return res;
}
}
//unlock somewhere here
return 0;
}
static ssize_t gpio_10389_set(struct device *dev, struct device_attribute *attr, char *buf, size_t count)
{
int result;
int value;
sscanf(buf, "%x", &value);
result = gpio_10389_ctrl(dev,value);
if (result<0) return result;
return count;
}
static ssize_t gpio_10389_get(struct device *dev, struct device_attribute *attr, char *buf)
{
int i;
unsigned int res=0;
struct elphel393_pwr_data_t *clientdata=platform_get_drvdata(to_platform_device(dev));
// just 4 of them
for (i=16;i<20;i++){
if (pwr_gpio[i].label){
res += ((clientdata->pwr_gpio[i].out_val)?1:0)<<(i-16);
}
}
return sprintf(buf,"%02x\n",res);
}
static ssize_t gpio_poweroff(struct device *dev, struct device_attribute *attr, char *buf, size_t count)
{
int rc=gpio_shutdown(dev);
if (rc<0) return rc;
return count;
}
int gpio_shutdown(struct device *dev) int gpio_shutdown(struct device *dev)
{ {
int gpio_shutdown_index=get_gpio_index_by_name("NSHUTDOWN"); int gpio_shutdown_index=get_gpio_index_by_name("NSHUTDOWN");
...@@ -1157,11 +1209,8 @@ static int elphel393_pwr_probe(struct platform_device *pdev) ...@@ -1157,11 +1209,8 @@ static int elphel393_pwr_probe(struct platform_device *pdev)
for (i=0;i<ARRAY_SIZE(pwr_gpio);i++) if (pwr_gpio[i].label){ for (i=0;i<ARRAY_SIZE(pwr_gpio);i++) if (pwr_gpio[i].label){
clientdata->pwr_gpio[i].label=pwr_gpio[i].label; clientdata->pwr_gpio[i].label=pwr_gpio[i].label;
clientdata->pwr_gpio[i].pin=base[i>>3]+(i & 7); clientdata->pwr_gpio[i].pin=base[i>>3]+(i & 7);
if (i<16) { if (i<16) clientdata->pwr_gpio[i].dir=0; /* input */
clientdata->pwr_gpio[i].dir=0; /* input */ else clientdata->pwr_gpio[i].dir=1; /* output */
}else{
clientdata->pwr_gpio[i].dir=1; /* output */
}
clientdata->pwr_gpio[i].out_val=0; clientdata->pwr_gpio[i].out_val=0;
rc=gpio_request(clientdata->pwr_gpio[i].pin, clientdata->pwr_gpio[i].label); rc=gpio_request(clientdata->pwr_gpio[i].pin, clientdata->pwr_gpio[i].label);
if (rc<0){ if (rc<0){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment