int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { struct nouveau_connector *nv_connector = nouveau_connector(connector); struct acpi_device *acpidev; acpi_handle handle; int type, ret; void *edid; switch (connector->connector_type) { case DRM_MODE_CONNECTOR_LVDS: case DRM_MODE_CONNECTOR_eDP: type = ACPI_VIDEO_DISPLAY_LCD; break; default: return -EINVAL; } handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); if (!handle) return -ENODEV; ret = acpi_bus_get_device(handle, &acpidev); if (ret) return -ENODEV; ret = acpi_video_get_edid(acpidev, type, -1, &edid); if (ret < 0) return ret; nv_connector->edid = edid; return 0; }
void nouveau_backlight_fini(struct drm_connector *connector) { struct nouveau_connector *nv_conn = nouveau_connector(connector); struct nouveau_backlight *bl = nv_conn->backlight; if (!bl) return; if (bl->id >= 0) ida_simple_remove(&bl_ida, bl->id); backlight_device_unregister(bl->dev); nv_conn->backlight = NULL; kfree(bl); }
int nouveau_backlight_init(struct drm_connector *connector) { struct nouveau_drm *drm = nouveau_drm(connector->dev); struct nouveau_backlight *bl; struct nouveau_encoder *nv_encoder = NULL; struct nvif_device *device = &drm->client.device; char backlight_name[BL_NAME_SIZE]; struct backlight_properties props = {0}; const struct backlight_ops *ops; int ret; if (apple_gmux_present()) { NV_INFO_ONCE(drm, "Apple GMUX detected: not registering Nouveau backlight interface\n"); return 0; } if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) nv_encoder = find_encoder(connector, DCB_OUTPUT_DP); else return 0; if (!nv_encoder) return 0; switch (device->info.family) { case NV_DEVICE_INFO_V0_CURIE: ret = nv40_backlight_init(nv_encoder, &props, &ops); break; case NV_DEVICE_INFO_V0_TESLA: case NV_DEVICE_INFO_V0_FERMI: case NV_DEVICE_INFO_V0_KEPLER: case NV_DEVICE_INFO_V0_MAXWELL: ret = nv50_backlight_init(nv_encoder, &props, &ops); break; default: return 0; } if (ret == -ENODEV) return 0; else if (ret) return ret; bl = kzalloc(sizeof(*bl), GFP_KERNEL); if (!bl) return -ENOMEM; if (!nouveau_get_backlight_name(backlight_name, bl)) { NV_ERROR(drm, "Failed to retrieve a unique name for the backlight interface\n"); goto fail_alloc; } bl->dev = backlight_device_register(backlight_name, connector->kdev, nv_encoder, ops, &props); if (IS_ERR(bl->dev)) { if (bl->id >= 0) ida_simple_remove(&bl_ida, bl->id); ret = PTR_ERR(bl->dev); goto fail_alloc; } nouveau_connector(connector)->backlight = bl; bl->dev->props.brightness = bl->dev->ops->get_brightness(bl->dev); backlight_update_status(bl->dev); return 0; fail_alloc: kfree(bl); return ret; }