18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2009 Red Hat <mjg@redhat.com> 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 58c2ecf20Sopenharmony_ci * a copy of this software and associated documentation files (the 68c2ecf20Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 78c2ecf20Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 88c2ecf20Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 98c2ecf20Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 108c2ecf20Sopenharmony_ci * the following conditions: 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the 138c2ecf20Sopenharmony_ci * next paragraph) shall be included in all copies or substantial 148c2ecf20Sopenharmony_ci * portions of the Software. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 178c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 188c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 198c2ecf20Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 208c2ecf20Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 218c2ecf20Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 228c2ecf20Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * Authors: 288c2ecf20Sopenharmony_ci * Matthew Garrett <mjg@redhat.com> 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * Register locations derived from NVClock by Roderick Colenbrander 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#include <linux/apple-gmux.h> 348c2ecf20Sopenharmony_ci#include <linux/backlight.h> 358c2ecf20Sopenharmony_ci#include <linux/idr.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include "nouveau_drv.h" 388c2ecf20Sopenharmony_ci#include "nouveau_reg.h" 398c2ecf20Sopenharmony_ci#include "nouveau_encoder.h" 408c2ecf20Sopenharmony_ci#include "nouveau_connector.h" 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic struct ida bl_ida; 438c2ecf20Sopenharmony_ci#define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0' 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistruct nouveau_backlight { 468c2ecf20Sopenharmony_ci struct backlight_device *dev; 478c2ecf20Sopenharmony_ci int id; 488c2ecf20Sopenharmony_ci}; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistatic bool 518c2ecf20Sopenharmony_cinouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], 528c2ecf20Sopenharmony_ci struct nouveau_backlight *bl) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci const int nb = ida_alloc_max(&bl_ida, 99, GFP_KERNEL); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci if (nb < 0) 578c2ecf20Sopenharmony_ci return false; 588c2ecf20Sopenharmony_ci if (nb > 0) 598c2ecf20Sopenharmony_ci snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); 608c2ecf20Sopenharmony_ci else 618c2ecf20Sopenharmony_ci snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight"); 628c2ecf20Sopenharmony_ci bl->id = nb; 638c2ecf20Sopenharmony_ci return true; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic int 678c2ecf20Sopenharmony_cinv40_get_intensity(struct backlight_device *bd) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = bl_get_data(bd); 708c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 718c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 728c2ecf20Sopenharmony_ci int val = (nvif_rd32(device, NV40_PMC_BACKLIGHT) & 738c2ecf20Sopenharmony_ci NV40_PMC_BACKLIGHT_MASK) >> 16; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci return val; 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic int 798c2ecf20Sopenharmony_cinv40_set_intensity(struct backlight_device *bd) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = bl_get_data(bd); 828c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 838c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 848c2ecf20Sopenharmony_ci int val = bd->props.brightness; 858c2ecf20Sopenharmony_ci int reg = nvif_rd32(device, NV40_PMC_BACKLIGHT); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci nvif_wr32(device, NV40_PMC_BACKLIGHT, 888c2ecf20Sopenharmony_ci (val << 16) | (reg & ~NV40_PMC_BACKLIGHT_MASK)); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci return 0; 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic const struct backlight_ops nv40_bl_ops = { 948c2ecf20Sopenharmony_ci .options = BL_CORE_SUSPENDRESUME, 958c2ecf20Sopenharmony_ci .get_brightness = nv40_get_intensity, 968c2ecf20Sopenharmony_ci .update_status = nv40_set_intensity, 978c2ecf20Sopenharmony_ci}; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_cistatic int 1008c2ecf20Sopenharmony_cinv40_backlight_init(struct nouveau_encoder *encoder, 1018c2ecf20Sopenharmony_ci struct backlight_properties *props, 1028c2ecf20Sopenharmony_ci const struct backlight_ops **ops) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(encoder->base.base.dev); 1058c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci if (!(nvif_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK)) 1088c2ecf20Sopenharmony_ci return -ENODEV; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci props->type = BACKLIGHT_RAW; 1118c2ecf20Sopenharmony_ci props->max_brightness = 31; 1128c2ecf20Sopenharmony_ci *ops = &nv40_bl_ops; 1138c2ecf20Sopenharmony_ci return 0; 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cistatic int 1178c2ecf20Sopenharmony_cinv50_get_intensity(struct backlight_device *bd) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = bl_get_data(bd); 1208c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 1218c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 1228c2ecf20Sopenharmony_ci int or = ffs(nv_encoder->dcb->or) - 1; 1238c2ecf20Sopenharmony_ci u32 div = 1025; 1248c2ecf20Sopenharmony_ci u32 val; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci val = nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(or)); 1278c2ecf20Sopenharmony_ci val &= NV50_PDISP_SOR_PWM_CTL_VAL; 1288c2ecf20Sopenharmony_ci return ((val * 100) + (div / 2)) / div; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic int 1328c2ecf20Sopenharmony_cinv50_set_intensity(struct backlight_device *bd) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = bl_get_data(bd); 1358c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 1368c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 1378c2ecf20Sopenharmony_ci int or = ffs(nv_encoder->dcb->or) - 1; 1388c2ecf20Sopenharmony_ci u32 div = 1025; 1398c2ecf20Sopenharmony_ci u32 val = (bd->props.brightness * div) / 100; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or), 1428c2ecf20Sopenharmony_ci NV50_PDISP_SOR_PWM_CTL_NEW | val); 1438c2ecf20Sopenharmony_ci return 0; 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic const struct backlight_ops nv50_bl_ops = { 1478c2ecf20Sopenharmony_ci .options = BL_CORE_SUSPENDRESUME, 1488c2ecf20Sopenharmony_ci .get_brightness = nv50_get_intensity, 1498c2ecf20Sopenharmony_ci .update_status = nv50_set_intensity, 1508c2ecf20Sopenharmony_ci}; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistatic int 1538c2ecf20Sopenharmony_cinva3_get_intensity(struct backlight_device *bd) 1548c2ecf20Sopenharmony_ci{ 1558c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = bl_get_data(bd); 1568c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 1578c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 1588c2ecf20Sopenharmony_ci int or = ffs(nv_encoder->dcb->or) - 1; 1598c2ecf20Sopenharmony_ci u32 div, val; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or)); 1628c2ecf20Sopenharmony_ci val = nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(or)); 1638c2ecf20Sopenharmony_ci val &= NVA3_PDISP_SOR_PWM_CTL_VAL; 1648c2ecf20Sopenharmony_ci if (div && div >= val) 1658c2ecf20Sopenharmony_ci return ((val * 100) + (div / 2)) / div; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci return 100; 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistatic int 1718c2ecf20Sopenharmony_cinva3_set_intensity(struct backlight_device *bd) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = bl_get_data(bd); 1748c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 1758c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 1768c2ecf20Sopenharmony_ci int or = ffs(nv_encoder->dcb->or) - 1; 1778c2ecf20Sopenharmony_ci u32 div, val; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci div = nvif_rd32(device, NV50_PDISP_SOR_PWM_DIV(or)); 1808c2ecf20Sopenharmony_ci val = (bd->props.brightness * div) / 100; 1818c2ecf20Sopenharmony_ci if (div) { 1828c2ecf20Sopenharmony_ci nvif_wr32(device, NV50_PDISP_SOR_PWM_CTL(or), 1838c2ecf20Sopenharmony_ci val | 1848c2ecf20Sopenharmony_ci NV50_PDISP_SOR_PWM_CTL_NEW | 1858c2ecf20Sopenharmony_ci NVA3_PDISP_SOR_PWM_CTL_UNK); 1868c2ecf20Sopenharmony_ci return 0; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci return -EINVAL; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic const struct backlight_ops nva3_bl_ops = { 1938c2ecf20Sopenharmony_ci .options = BL_CORE_SUSPENDRESUME, 1948c2ecf20Sopenharmony_ci .get_brightness = nva3_get_intensity, 1958c2ecf20Sopenharmony_ci .update_status = nva3_set_intensity, 1968c2ecf20Sopenharmony_ci}; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic int 1998c2ecf20Sopenharmony_cinv50_backlight_init(struct nouveau_encoder *nv_encoder, 2008c2ecf20Sopenharmony_ci struct backlight_properties *props, 2018c2ecf20Sopenharmony_ci const struct backlight_ops **ops) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); 2048c2ecf20Sopenharmony_ci struct nvif_object *device = &drm->client.device.object; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(ffs(nv_encoder->dcb->or) - 1))) 2078c2ecf20Sopenharmony_ci return -ENODEV; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci if (drm->client.device.info.chipset <= 0xa0 || 2108c2ecf20Sopenharmony_ci drm->client.device.info.chipset == 0xaa || 2118c2ecf20Sopenharmony_ci drm->client.device.info.chipset == 0xac) 2128c2ecf20Sopenharmony_ci *ops = &nv50_bl_ops; 2138c2ecf20Sopenharmony_ci else 2148c2ecf20Sopenharmony_ci *ops = &nva3_bl_ops; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci props->type = BACKLIGHT_RAW; 2178c2ecf20Sopenharmony_ci props->max_brightness = 100; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci return 0; 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ciint 2238c2ecf20Sopenharmony_cinouveau_backlight_init(struct drm_connector *connector) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci struct nouveau_drm *drm = nouveau_drm(connector->dev); 2268c2ecf20Sopenharmony_ci struct nouveau_backlight *bl; 2278c2ecf20Sopenharmony_ci struct nouveau_encoder *nv_encoder = NULL; 2288c2ecf20Sopenharmony_ci struct nvif_device *device = &drm->client.device; 2298c2ecf20Sopenharmony_ci char backlight_name[BL_NAME_SIZE]; 2308c2ecf20Sopenharmony_ci struct backlight_properties props = {0}; 2318c2ecf20Sopenharmony_ci const struct backlight_ops *ops; 2328c2ecf20Sopenharmony_ci int ret; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci if (apple_gmux_present()) { 2358c2ecf20Sopenharmony_ci NV_INFO_ONCE(drm, "Apple GMUX detected: not registering Nouveau backlight interface\n"); 2368c2ecf20Sopenharmony_ci return 0; 2378c2ecf20Sopenharmony_ci } 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) 2408c2ecf20Sopenharmony_ci nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); 2418c2ecf20Sopenharmony_ci else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) 2428c2ecf20Sopenharmony_ci nv_encoder = find_encoder(connector, DCB_OUTPUT_DP); 2438c2ecf20Sopenharmony_ci else 2448c2ecf20Sopenharmony_ci return 0; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci if (!nv_encoder) 2478c2ecf20Sopenharmony_ci return 0; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci switch (device->info.family) { 2508c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_CURIE: 2518c2ecf20Sopenharmony_ci ret = nv40_backlight_init(nv_encoder, &props, &ops); 2528c2ecf20Sopenharmony_ci break; 2538c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_TESLA: 2548c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_FERMI: 2558c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_KEPLER: 2568c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_MAXWELL: 2578c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_PASCAL: 2588c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_VOLTA: 2598c2ecf20Sopenharmony_ci case NV_DEVICE_INFO_V0_TURING: 2608c2ecf20Sopenharmony_ci ret = nv50_backlight_init(nv_encoder, &props, &ops); 2618c2ecf20Sopenharmony_ci break; 2628c2ecf20Sopenharmony_ci default: 2638c2ecf20Sopenharmony_ci return 0; 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci if (ret == -ENODEV) 2678c2ecf20Sopenharmony_ci return 0; 2688c2ecf20Sopenharmony_ci else if (ret) 2698c2ecf20Sopenharmony_ci return ret; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci bl = kzalloc(sizeof(*bl), GFP_KERNEL); 2728c2ecf20Sopenharmony_ci if (!bl) 2738c2ecf20Sopenharmony_ci return -ENOMEM; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci if (!nouveau_get_backlight_name(backlight_name, bl)) { 2768c2ecf20Sopenharmony_ci NV_ERROR(drm, "Failed to retrieve a unique name for the backlight interface\n"); 2778c2ecf20Sopenharmony_ci goto fail_alloc; 2788c2ecf20Sopenharmony_ci } 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci bl->dev = backlight_device_register(backlight_name, connector->kdev, 2818c2ecf20Sopenharmony_ci nv_encoder, ops, &props); 2828c2ecf20Sopenharmony_ci if (IS_ERR(bl->dev)) { 2838c2ecf20Sopenharmony_ci if (bl->id >= 0) 2848c2ecf20Sopenharmony_ci ida_free(&bl_ida, bl->id); 2858c2ecf20Sopenharmony_ci ret = PTR_ERR(bl->dev); 2868c2ecf20Sopenharmony_ci goto fail_alloc; 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci nouveau_connector(connector)->backlight = bl; 2908c2ecf20Sopenharmony_ci bl->dev->props.brightness = bl->dev->ops->get_brightness(bl->dev); 2918c2ecf20Sopenharmony_ci backlight_update_status(bl->dev); 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci return 0; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cifail_alloc: 2968c2ecf20Sopenharmony_ci kfree(bl); 2978c2ecf20Sopenharmony_ci return ret; 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_civoid 3018c2ecf20Sopenharmony_cinouveau_backlight_fini(struct drm_connector *connector) 3028c2ecf20Sopenharmony_ci{ 3038c2ecf20Sopenharmony_ci struct nouveau_connector *nv_conn = nouveau_connector(connector); 3048c2ecf20Sopenharmony_ci struct nouveau_backlight *bl = nv_conn->backlight; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (!bl) 3078c2ecf20Sopenharmony_ci return; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci if (bl->id >= 0) 3108c2ecf20Sopenharmony_ci ida_free(&bl_ida, bl->id); 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci backlight_device_unregister(bl->dev); 3138c2ecf20Sopenharmony_ci nv_conn->backlight = NULL; 3148c2ecf20Sopenharmony_ci kfree(bl); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_civoid 3188c2ecf20Sopenharmony_cinouveau_backlight_ctor(void) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci ida_init(&bl_ida); 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_civoid 3248c2ecf20Sopenharmony_cinouveau_backlight_dtor(void) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci ida_destroy(&bl_ida); 3278c2ecf20Sopenharmony_ci} 328