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

+'shutdown -hP ...'

parent 09009b1c
......@@ -41,6 +41,7 @@
#define GPIO_CHIP1_ADDR 0x20
#define GPIO_CHIP2_ADDR 0x21
#define GPIO_10389_U4_ADDR 0x25
#define LTC3589_ADDR 0x34
/* TODO: set resistors in device tree to accommodate different revisions ( elphel393_pwr,vp15_r1 = <357000>)*/
......@@ -70,7 +71,7 @@ struct pwr_gpio_t {
};
struct elphel393_pwr_data_t {
int chip_i2c_addr[3];
int chip_i2c_addr[4];
struct device * ltc3489_dev;
struct pwr_gpio_t pwr_gpio [16];
int simulate; /* do not perform actual i2c writes */
......@@ -221,9 +222,20 @@ static struct pwr_gpio_t pwr_gpio[16]={
{ NULL, 12, 0, 0}, /* Not connected */
{ NULL, 13, 0, 0}, /* Not connected */
{"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,
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
char *buf),
......@@ -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 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 reenable_por(struct device *dev);
static int wait_all_pgood(struct device *dev);
......@@ -291,16 +303,16 @@ static int get_pgood(struct device *dev, int chn);
*/
/* 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(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_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_bad, SYSFS_PERMISSIONS & SYSFS_READONLY, pbad_show, NULL);
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(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(power_good, SYSFS_PERMISSIONS & SYSFS_READONLY, pgood_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(power_off, SYSFS_PERMISSIONS , NULL, gpio_shutdown);
static struct attribute *root_dev_attrs[] = {
......@@ -312,7 +324,7 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_power_good.attr,
&dev_attr_power_bad.attr,
&dev_attr_enable_por.attr,
&dev_attr_power_shutdown.attr,
&dev_attr_power_off.attr,
NULL
};
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
return count;
}
int shutdown(struct device *dev)
int gpio_shutdown(struct device *dev)
{
int gpio_shutdown_index=get_gpio_index_by_name("NSHUTDOWN");
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);
}
......@@ -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]);
}
static void shutdown(void){
gpio_shutdown(shutdown_dev);
}
static int elphel393_pwr_probe(struct platform_device *pdev)
{
struct gpio_chip *chip;
// struct device * ltc3489_dev;
int i,rc;
int base[2];
int base[3];
struct i2c_client *ltc3589_client;
struct elphel393_pwr_data_t *clientdata = NULL;
shutdown_dev = &pdev->dev;
dev_info(&pdev->dev,"Probing elphel393-pwr\n");
clientdata = devm_kzalloc(&pdev->dev, sizeof(*clientdata), GFP_KERNEL);
clientdata->pgoot_timeout=DEAFULT_TIMEOUT;
clientdata->pinstrapped_oven=PINSTRAPPED_OVEN;
clientdata->chip_i2c_addr[0]=0x20;
clientdata->chip_i2c_addr[1]=0x21;
clientdata->chip_i2c_addr[2]=0x34;
clientdata->chip_i2c_addr[0]=GPIO_CHIP1_ADDR;
clientdata->chip_i2c_addr[1]=GPIO_CHIP2_ADDR;
clientdata->chip_i2c_addr[2]=GPIO_10389_U4_ADDR;
clientdata->chip_i2c_addr[3]=LTC3589_ADDR;
platform_set_drvdata(pdev, clientdata);
elphel393_pwr_sysfs_register(pdev);
......@@ -1131,7 +1149,7 @@ static int elphel393_pwr_probe(struct platform_device *pdev)
mutex_init(&clientdata->lock);
/* 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);
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]);
......@@ -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){
clientdata->pwr_gpio[i].label=pwr_gpio[i].label;
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;
rc=gpio_request(clientdata->pwr_gpio[i].pin, clientdata->pwr_gpio[i].label);
if (rc<0){
......@@ -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);
}
}
/* find ltc3589 */
clientdata->ltc3489_dev=find_device_by_i2c_addr(LTC3589_ADDR);
if (!clientdata->ltc3489_dev){
......@@ -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));
elphel393_pwr_init_of(pdev);
pm_power_off = shutdown;
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