static void * nvkm_gpio_dtor(struct nvkm_subdev *subdev) { struct nvkm_gpio *gpio = nvkm_gpio(subdev); nvkm_event_fini(&gpio->event); return gpio; }
static int nvkm_gpio_init(struct nvkm_subdev *subdev) { struct nvkm_gpio *gpio = nvkm_gpio(subdev); if (dmi_check_system(gpio_reset_ids)) nvkm_gpio_reset(gpio, DCB_GPIO_UNUSED); return 0; }
static void nvkm_gpio_intr(struct nvkm_subdev *subdev) { struct nvkm_gpio *gpio = nvkm_gpio(subdev); u32 hi, lo, i; gpio->func->intr_stat(gpio, &hi, &lo); for (i = 0; (hi | lo) && i < gpio->func->lines; i++) { struct nvkm_gpio_ntfy_rep rep = { .mask = (NVKM_GPIO_HI * !!(hi & (1 << i))) | (NVKM_GPIO_LO * !!(lo & (1 << i))), }; nvkm_event_send(&gpio->event, rep.mask, i, &rep, sizeof(rep)); } } static int nvkm_gpio_fini(struct nvkm_subdev *subdev, bool suspend) { struct nvkm_gpio *gpio = nvkm_gpio(subdev); u32 mask = (1ULL << gpio->func->lines) - 1; gpio->func->intr_mask(gpio, NVKM_GPIO_TOGGLED, mask, 0); gpio->func->intr_stat(gpio, &mask, &mask); return 0; } static struct dmi_system_id gpio_reset_ids[] = { { .ident = "Apple Macbook 10,1", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro10,1"), } }, { } };
static int nvkm_fanpwm_get(struct nvkm_therm *therm) { struct nvkm_therm_priv *tpriv = (void *)therm; struct nvkm_fanpwm_priv *priv = (void *)tpriv->fan; struct nvkm_gpio *gpio = nvkm_gpio(therm); int card_type = nv_device(therm)->card_type; u32 divs, duty; int ret; ret = therm->pwm_get(therm, priv->func.line, &divs, &duty); if (ret == 0 && divs) { divs = max(divs, duty); if (card_type <= NV_40 || (priv->func.log[0] & 1)) duty = divs - duty; return (duty * 100) / divs; } return gpio->get(gpio, 0, priv->func.func, priv->func.line) * 100; }