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

+'shutdown -hP ...'

parent 09009b1c
Loading
Loading
Loading
Loading
+45 −20
Original line number Diff line number Diff line
@@ -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);
@@ -300,7 +312,7 @@ static DEVICE_ATTR(channels_dis, SYSFS_PERMISSIONS, channel
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(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);
    	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;
}