static int radio_off_telit(void) { int value, ret; struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON"); struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF"); struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST"); if (!onoff_pin || !pwrmon_pin || !rst_pin) { return -ENODEV; } value = gpio_get_value(pwrmon_pin->pin.gpio); if(value == 0) { log_error("radio is already off"); return -EINVAL; } // drive on/off pin low for at least 3 sec log_info("shutting down radio"); ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(3500); // set on/off pin high ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } // wait for radio to power off msleep(5000); // check that power is low value = gpio_get_value(pwrmon_pin->pin.gpio); if(value != 0) { log_warning("radio is still on. performing radio reset."); //Perform Hard Reset ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(500); // set pin high ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } } else { log_info("radio has been shut down"); } return ret; } static int radio_on_telit(void) { int value, ret; struct gpio_pin *pwrmon_pin = gpio_pin_by_name("PWRMON"); struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF"); struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST"); if (!onoff_pin || !pwrmon_pin || !rst_pin) { return -ENODEV; } value = gpio_get_value(pwrmon_pin->pin.gpio); if(value != 0) { log_error("radio is already on"); return -EINVAL; } // drive on/off pin low for at least 5 sec log_info("turning on radio"); ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(5500); // set on/off pin high ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(200); // check that power is high value = gpio_get_value(pwrmon_pin->pin.gpio); if(value == 0) { log_warning("radio is still off. performing radio reset"); //Perform Hard Reset ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(500); // set pin high ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } } else { log_info("radio has been turned on"); } return ret; } static ssize_t mts_attr_store_radio_power_telit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; int err; if (sscanf(buf, "%i", &value) != 1) { return -EINVAL; } if (value == 0) { mutex_lock(&mts_io_mutex); err = radio_off_telit(); mutex_unlock(&mts_io_mutex); } else { mutex_lock(&mts_io_mutex); err = radio_on_telit(); mutex_unlock(&mts_io_mutex); } if (err) { return err; } return count; } static int radio_reset_telit(void) { int ret; struct gpio_pin *rst_pin = gpio_pin_by_name("3G_RST"); struct gpio_pin *onoff_pin = gpio_pin_by_name("3G_ONOFF"); if (!rst_pin || !onoff_pin) { return -ENODEV; } // drive reset pin low for 500ms ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 0, rst_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(500); // set pin high ret = gpio_direction_output_pullup(rst_pin->pin.gpio, 1, rst_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } // wait for 2 sec before toggling on/off pin msleep(2000); // drive on/off pin low for 6 sec ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 0, onoff_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } msleep(6000); // set on/off pin high ret = gpio_direction_output_pullup(onoff_pin->pin.gpio, 1, onoff_pin->pin.flags & GPIOF_PULLUP); if (ret) { return ret; } return ret; } static ssize_t mts_attr_store_radio_reset_telit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int value; int err; if (sscanf(buf, "%i", &value) != 1) { return -EINVAL; } if (value != 0) { return -EINVAL; } mutex_lock(&mts_io_mutex); err = radio_reset_telit(); mutex_unlock(&mts_io_mutex); if (err) { return err; } return count; } static DEVICE_ATTR_MTS(dev_attr_radio_power_telit, "radio-power", mts_attr_show_gpio_pin, mts_attr_store_radio_power_telit); static DEVICE_ATTR_MTS(dev_attr_radio_reset_telit, "radio-reset", mts_attr_show_gpio_pin, mts_attr_store_radio_reset_telit);