0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <subdev/volt.h>
0025 #include <subdev/bios.h>
0026 #include <subdev/bios/gpio.h>
0027 #include <subdev/gpio.h>
0028 #include "priv.h"
0029
0030 static const u8 tags[] = {
0031 DCB_GPIO_VID0, DCB_GPIO_VID1, DCB_GPIO_VID2, DCB_GPIO_VID3,
0032 DCB_GPIO_VID4, DCB_GPIO_VID5, DCB_GPIO_VID6, DCB_GPIO_VID7,
0033 };
0034
0035 int
0036 nvkm_voltgpio_get(struct nvkm_volt *volt)
0037 {
0038 struct nvkm_gpio *gpio = volt->subdev.device->gpio;
0039 u8 vid = 0;
0040 int i;
0041
0042 for (i = 0; i < ARRAY_SIZE(tags); i++) {
0043 if (volt->vid_mask & (1 << i)) {
0044 int ret = nvkm_gpio_get(gpio, 0, tags[i], 0xff);
0045 if (ret < 0)
0046 return ret;
0047 vid |= ret << i;
0048 }
0049 }
0050
0051 return vid;
0052 }
0053
0054 int
0055 nvkm_voltgpio_set(struct nvkm_volt *volt, u8 vid)
0056 {
0057 struct nvkm_gpio *gpio = volt->subdev.device->gpio;
0058 int i;
0059
0060 for (i = 0; i < ARRAY_SIZE(tags); i++, vid >>= 1) {
0061 if (volt->vid_mask & (1 << i)) {
0062 int ret = nvkm_gpio_set(gpio, 0, tags[i], 0xff, vid & 1);
0063 if (ret < 0)
0064 return ret;
0065 }
0066 }
0067
0068 return 0;
0069 }
0070
0071 int
0072 nvkm_voltgpio_init(struct nvkm_volt *volt)
0073 {
0074 struct nvkm_subdev *subdev = &volt->subdev;
0075 struct nvkm_gpio *gpio = subdev->device->gpio;
0076 struct dcb_gpio_func func;
0077 int i;
0078
0079
0080
0081
0082
0083
0084
0085 for (i = 0; i < ARRAY_SIZE(tags); i++) {
0086 if (volt->vid_mask & (1 << i)) {
0087 int ret = nvkm_gpio_find(gpio, 0, tags[i], 0xff, &func);
0088 if (ret) {
0089 if (ret != -ENOENT)
0090 return ret;
0091 nvkm_debug(subdev, "VID bit %d has no GPIO\n", i);
0092 volt->vid_mask &= ~(1 << i);
0093 }
0094 }
0095 }
0096
0097 return 0;
0098 }