6761 i2c裝置新增gpio控制裝置上電

2020-08-12 14:33:26

起初使用如下方式

&i2c1 {

        alsps@44 {
                ldo_hrs_pin = <&pio 177 0>;
                 ....
         };

};

在驅動中按如下的寫法

LDO_HRS_PIN = of_get_named_gpio(client->dev.of_node,"ldo_hrs_pin", 0);

gpio_request(LDO_HRS_PIN, "LDO_HRS_PIN");

上述寫法在32位元kernel上沒有問題,但是在64位元kernel上會報 invalid GPIO 23062,從而導致ic上電失敗,具體原因不詳,希望大牛們指點一二,爲了不耽誤專案進度,因此選擇用下面 下麪的方式進行控制。

dts中的寫法

&i2c1 {

        alsps@44 {
                 /* customization */
                 pinctrl-names = "hrs_en_low", "hrs_en_high";
                 pinctrl-0 = <&hrs_en_low>;
                 pinctrl-1 = <&hrs_en_high>;
                 status = "okay";
 
                 ....
         };

};

/* hrs3300 power control BEGIN*/
&pio {
       hrs_en_low:hrs_en_low@gpio177{
               pins_cmd_dat {
                       pinmux = <PINMUX_GPIO177__FUNC_GPIO177>;
                       slew-rate = <1>;
                       output-low;
               };
       };
       hrs_en_high:hrs_en_high@gpio177{
               pins_cmd_dat {
                       pinmux = <PINMUX_GPIO177__FUNC_GPIO177>;
                       slew-rate = <1>;
                       output-high;
               };
       };
};
/* hrs3300 power control end*/

驅動中的寫法:

probe中新增pin control的初始化函數 

static int hrs3300_i2c_probe(struct i2c_client *client, ...) {

    ...

    power_pinctrl_init(client);

    ...

}

static int power_pinctrl_init(struct i2c_client *client)
{
       int ret = 0;
       /* get pinctrl */
       power_pinctrl = devm_pinctrl_get(&client->dev);
       if (IS_ERR(power_pinctrl)) {
               printk("Failed to get hrs3300 pinctrl.\n");
               ret = PTR_ERR(power_pinctrl);
               return ret;
       }

       /* TODO: hrs3300 power XXX pin initialization */
       power_xxx_high = pinctrl_lookup_state(
                       power_pinctrl, POWER_PINCTRL_STATE_XXX_HIGH);
       if (IS_ERR(power_xxx_high)) {
               printk("Failed to init (%s)\n", POWER_PINCTRL_STATE_XXX_HIGH);
               ret = PTR_ERR(power_xxx_high);
       }
       power_xxx_low = pinctrl_lookup_state(
                       power_pinctrl, POWER_PINCTRL_STATE_XXX_LOW);
       if (IS_ERR(power_xxx_low)) {
               printk("Failed to init (%s)\n", POWER_PINCTRL_STATE_XXX_LOW);
               ret = PTR_ERR(power_xxx_low);
       }

      return ret;
}

gpio控制的函數

static void hrs3300_power(struct hrate_hw *hw, unsigned int on) 
 {
        static unsigned int power_on = 0;
 
       if (power_xxx_low==NULL || power_xxx_high==NULL) {
               pr_err("%s pin not init\n");
               return;
       }
       if (!on && !IS_ERR(power_xxx_low))
               pinctrl_select_state(power_pinctrl, power_xxx_low);
       else if (on  && !IS_ERR(power_xxx_high))
               pinctrl_select_state(power_pinctrl, power_xxx_high);
       else
               pr_err("set err, pin\n");
 }

變數宣告如下
#define POWER_PINCTRL_STATE_XXX_HIGH "hrs_en_high"
#define POWER_PINCTRL_STATE_XXX_LOW  "hrs_en_low"

static struct pinctrl *power_pinctrl=NULL;
static struct pinctrl_state *power_xxx_high=NULL;
static struct pinctrl_state *power_xxx_low=NULL;

在此做個筆記