Commit 892b1912 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

+'shutdown -hP ...'

parent 09009b1c
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#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 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>)*/
...@@ -70,7 +71,7 @@ struct pwr_gpio_t { ...@@ -70,7 +71,7 @@ struct pwr_gpio_t {
}; };
struct elphel393_pwr_data_t { struct elphel393_pwr_data_t {
int chip_i2c_addr[3]; 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 [16];
int simulate; /* do not perform actual i2c writes */ int simulate; /* do not perform actual i2c writes */
...@@ -221,9 +222,20 @@ static struct pwr_gpio_t pwr_gpio[16]={ ...@@ -221,9 +222,20 @@ static struct pwr_gpio_t pwr_gpio[16]={
{ NULL, 12, 0, 0}, /* Not connected */ { NULL, 12, 0, 0}, /* Not connected */
{ NULL, 13, 0, 0}, /* Not connected */ { NULL, 13, 0, 0}, /* Not connected */
{"MGTAVTTGOOD",14, 0, 0}, /* (input) 1.2V linear regulator status (generated from 1.8V) */ {"MGTAVTTGOOD",14, 0, 0}, /* (input) 1.2V linear regulator status (generated from 1.8V) */
{"PGOOD18", 15, 0, 0} /* (input). Combines other voltages, can be monitored when DIS_POR is activated */ {"PGOOD18", 15, 0, 0}, /* (input). Combines other voltages, can be monitored when DIS_POR is activated */
/* 0x25: */
{ "FAN_CTL", 16, 1, 0}, /* Fan Control, 1 - on, 0 - off */
{ "DAS_DSS", 17, 1, 0}, /* ? */
{ "DEVSLP", 18, 1, 0}, /* ? */
{ "EPGMA", 19, 1, 0}, /* ? */
{ NULL, 20, 1, 0}, /* Not connected */
{ NULL, 21, 1, 0}, /* Not connected */
{ NULL, 22, 1, 0}, /* Not connected */
{ NULL, 23, 1, 0} /* Not connected */
}; };
static struct device * shutdown_dev;
static int make_group (struct device *dev, const char * name, static int make_group (struct device *dev, const char * name,
ssize_t (*show)(struct device *dev, struct device_attribute *attr, ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf), char *buf),
...@@ -252,7 +264,7 @@ static ssize_t enable_por_show(struct device *dev, struct device_attribute *attr ...@@ -252,7 +264,7 @@ static ssize_t enable_por_show(struct device *dev, struct device_attribute *attr
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 int por_ctrl(struct device *dev, int disable_por); static int por_ctrl(struct device *dev, int disable_por);
static int shutdown(struct device *dev); static int gpio_shutdown(struct device *dev);
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);
...@@ -291,16 +303,16 @@ static int get_pgood(struct device *dev, int chn); ...@@ -291,16 +303,16 @@ static int get_pgood(struct device *dev, int chn);
*/ */
/* root directory */ /* root directory */
static DEVICE_ATTR(simulate, SYSFS_PERMISSIONS, simulate_show, simulate_store); static DEVICE_ATTR(simulate, SYSFS_PERMISSIONS, simulate_show, simulate_store);
static DEVICE_ATTR(output_state, SYSFS_PERMISSIONS & SYSFS_READONLY, outputs_all_show, NULL); static DEVICE_ATTR(output_state, SYSFS_PERMISSIONS & SYSFS_READONLY, outputs_all_show, NULL);
static DEVICE_ATTR(configs, SYSFS_PERMISSIONS & SYSFS_READONLY, configs_all_show, NULL); static DEVICE_ATTR(configs, SYSFS_PERMISSIONS & SYSFS_READONLY, configs_all_show, NULL);
static DEVICE_ATTR(channels_en, SYSFS_PERMISSIONS, channels_en_show, channels_en_store); static DEVICE_ATTR(channels_en, SYSFS_PERMISSIONS, channels_en_show, channels_en_store);
static DEVICE_ATTR(channels_dis, SYSFS_PERMISSIONS, channels_dis_show, channels_dis_store); static DEVICE_ATTR(channels_dis, SYSFS_PERMISSIONS, channels_dis_show, channels_dis_store);
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_shutdown,SYSFS_PERMISSIONS , NULL, shutdown); static DEVICE_ATTR(power_off, SYSFS_PERMISSIONS , NULL, gpio_shutdown);
static struct attribute *root_dev_attrs[] = { static struct attribute *root_dev_attrs[] = {
...@@ -312,7 +324,7 @@ static struct attribute *root_dev_attrs[] = { ...@@ -312,7 +324,7 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_power_good.attr, &dev_attr_power_good.attr,
&dev_attr_power_bad.attr, &dev_attr_power_bad.attr,
&dev_attr_enable_por.attr, &dev_attr_enable_por.attr,
&dev_attr_power_shutdown.attr, &dev_attr_power_off.attr,
NULL NULL
}; };
static const struct attribute_group dev_attr_root_group = { static const struct attribute_group dev_attr_root_group = {
...@@ -577,11 +589,10 @@ static ssize_t enable_por_store(struct device *dev, struct device_attribute *att ...@@ -577,11 +589,10 @@ static ssize_t enable_por_store(struct device *dev, struct device_attribute *att
return count; return count;
} }
int 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");
if (gpio_shutdown_index<0) return gpio_shutdown_index; if (gpio_shutdown_index<0) return gpio_shutdown_index;
pr_info("POWER OFF\n");
return gpio_conf_by_index(dev, gpio_shutdown_index, 1, 0); return gpio_conf_by_index(dev, gpio_shutdown_index, 1, 0);
} }
...@@ -1106,23 +1117,30 @@ static int i2c_addr_gpiochip_match(struct gpio_chip *chip, void *data) ...@@ -1106,23 +1117,30 @@ static int i2c_addr_gpiochip_match(struct gpio_chip *chip, void *data)
return i2c_verify_client(chip->dev) && (client->addr==addr[0]); return i2c_verify_client(chip->dev) && (client->addr==addr[0]);
} }
static void shutdown(void){
gpio_shutdown(shutdown_dev);
}
static int elphel393_pwr_probe(struct platform_device *pdev) static int elphel393_pwr_probe(struct platform_device *pdev)
{ {
struct gpio_chip *chip; struct gpio_chip *chip;
// struct device * ltc3489_dev; // struct device * ltc3489_dev;
int i,rc; int i,rc;
int base[2]; int base[3];
struct i2c_client *ltc3589_client; struct i2c_client *ltc3589_client;
struct elphel393_pwr_data_t *clientdata = NULL; struct elphel393_pwr_data_t *clientdata = NULL;
shutdown_dev = &pdev->dev;
dev_info(&pdev->dev,"Probing elphel393-pwr\n"); dev_info(&pdev->dev,"Probing elphel393-pwr\n");
clientdata = devm_kzalloc(&pdev->dev, sizeof(*clientdata), GFP_KERNEL); clientdata = devm_kzalloc(&pdev->dev, sizeof(*clientdata), GFP_KERNEL);
clientdata->pgoot_timeout=DEAFULT_TIMEOUT; clientdata->pgoot_timeout=DEAFULT_TIMEOUT;
clientdata->pinstrapped_oven=PINSTRAPPED_OVEN; clientdata->pinstrapped_oven=PINSTRAPPED_OVEN;
clientdata->chip_i2c_addr[0]=0x20; clientdata->chip_i2c_addr[0]=GPIO_CHIP1_ADDR;
clientdata->chip_i2c_addr[1]=0x21; clientdata->chip_i2c_addr[1]=GPIO_CHIP2_ADDR;
clientdata->chip_i2c_addr[2]=0x34; clientdata->chip_i2c_addr[2]=GPIO_10389_U4_ADDR;
clientdata->chip_i2c_addr[3]=LTC3589_ADDR;
platform_set_drvdata(pdev, clientdata); platform_set_drvdata(pdev, clientdata);
elphel393_pwr_sysfs_register(pdev); elphel393_pwr_sysfs_register(pdev);
...@@ -1131,7 +1149,7 @@ static int elphel393_pwr_probe(struct platform_device *pdev) ...@@ -1131,7 +1149,7 @@ static int elphel393_pwr_probe(struct platform_device *pdev)
mutex_init(&clientdata->lock); mutex_init(&clientdata->lock);
/* locate GPIO chips by i2c address */ /* locate GPIO chips by i2c address */
for (i=0;i<2;i++){ for (i=0;i<3;i++){
chip = gpiochip_find(&clientdata->chip_i2c_addr[i], i2c_addr_gpiochip_match); chip = gpiochip_find(&clientdata->chip_i2c_addr[i], i2c_addr_gpiochip_match);
base[i]=chip->base; base[i]=chip->base;
dev_dbg(&pdev->dev,"Found gpio_chip with i2c_addr=0x%02x, label=%s, base=0x%x\n",clientdata->chip_i2c_addr[i],chip->label,base[i]); dev_dbg(&pdev->dev,"Found gpio_chip with i2c_addr=0x%02x, label=%s, base=0x%x\n",clientdata->chip_i2c_addr[i],chip->label,base[i]);
...@@ -1139,7 +1157,11 @@ static int elphel393_pwr_probe(struct platform_device *pdev) ...@@ -1139,7 +1157,11 @@ 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);
clientdata->pwr_gpio[i].dir=0; /* input */ if (i<16) {
clientdata->pwr_gpio[i].dir=0; /* input */
}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){
...@@ -1149,6 +1171,7 @@ static int elphel393_pwr_probe(struct platform_device *pdev) ...@@ -1149,6 +1171,7 @@ static int elphel393_pwr_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev,"Confirmed request GPIO[%d] with label %s\n",clientdata->pwr_gpio[i].pin,clientdata->pwr_gpio[i].label); dev_dbg(&pdev->dev,"Confirmed request GPIO[%d] with label %s\n",clientdata->pwr_gpio[i].pin,clientdata->pwr_gpio[i].label);
} }
} }
/* find ltc3589 */ /* find ltc3589 */
clientdata->ltc3489_dev=find_device_by_i2c_addr(LTC3589_ADDR); clientdata->ltc3489_dev=find_device_by_i2c_addr(LTC3589_ADDR);
if (!clientdata->ltc3489_dev){ if (!clientdata->ltc3489_dev){
...@@ -1161,6 +1184,8 @@ static int elphel393_pwr_probe(struct platform_device *pdev) ...@@ -1161,6 +1184,8 @@ static int elphel393_pwr_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev,"LTC3589 status= 0x%02x\n",ltc3589_read_field(ltc3589_client, LTC3589_AWE_PGSTAT)); dev_dbg(&pdev->dev,"LTC3589 status= 0x%02x\n",ltc3589_read_field(ltc3589_client, LTC3589_AWE_PGSTAT));
elphel393_pwr_init_of(pdev); elphel393_pwr_init_of(pdev);
pm_power_off = shutdown;
return 0; return 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