drivers/phy/motorola/phy-mapphone-mdm6600.c

Source file repositories/reference/linux-study-clean/drivers/phy/motorola/phy-mapphone-mdm6600.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/motorola/phy-mapphone-mdm6600.c
Extension
.c
Size
18475 bytes
Lines
670
Domain
Driver Families
Bucket
drivers/phy
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct phy_mdm6600 {
	struct device *dev;
	struct phy *generic_phy;
	struct phy_provider *phy_provider;
	struct gpio_desc *ctrl_gpios[PHY_MDM6600_NR_CTRL_LINES];
	struct gpio_descs *mode_gpios;
	struct gpio_descs *status_gpios;
	struct gpio_descs *cmd_gpios;
	struct delayed_work bootup_work;
	struct delayed_work status_work;
	struct delayed_work modem_wake_work;
	struct completion ack;
	bool enabled;				/* mdm6600 phy enabled */
	bool running;				/* mdm6600 boot done */
	bool awake;				/* mdm6600 respnds on n_gsm */
	int status;
};

static int phy_mdm6600_init(struct phy *x)
{
	struct phy_mdm6600 *ddata = phy_get_drvdata(x);
	struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];

	if (!ddata->enabled)
		return -EPROBE_DEFER;

	gpiod_set_value_cansleep(enable_gpio, 0);

	return 0;
}

static int phy_mdm6600_power_on(struct phy *x)
{
	struct phy_mdm6600 *ddata = phy_get_drvdata(x);
	struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];

	if (!ddata->enabled)
		return -ENODEV;

	gpiod_set_value_cansleep(enable_gpio, 1);

	/* Allow aggressive PM for USB, it's only needed for n_gsm port */
	if (pm_runtime_enabled(&x->dev))
		phy_pm_runtime_put(x);

	return 0;
}

static int phy_mdm6600_power_off(struct phy *x)
{
	struct phy_mdm6600 *ddata = phy_get_drvdata(x);
	struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE];
	int error;

	if (!ddata->enabled)
		return -ENODEV;

	/* Paired with phy_pm_runtime_put() in phy_mdm6600_power_on() */
	if (pm_runtime_enabled(&x->dev)) {
		error = phy_pm_runtime_get(x);
		if (error < 0 && error != -EINPROGRESS)
			dev_warn(ddata->dev, "%s: phy_pm_runtime_get: %i\n",
				 __func__, error);
	}

	gpiod_set_value_cansleep(enable_gpio, 0);

	return 0;
}

static const struct phy_ops gpio_usb_ops = {
	.init = phy_mdm6600_init,
	.power_on = phy_mdm6600_power_on,
	.power_off = phy_mdm6600_power_off,
	.owner = THIS_MODULE,
};

/**
 * phy_mdm6600_cmd() - send a command request to mdm6600
 * @ddata: device driver data
 * @val: value of cmd to be set
 *
 * Configures the three command request GPIOs to the specified value.
 */
static void phy_mdm6600_cmd(struct phy_mdm6600 *ddata, int val)
{
	DECLARE_BITMAP(values, PHY_MDM6600_NR_CMD_LINES);

	values[0] = val;

Annotation

Implementation Notes