diff options
author | Dave Airlie <airlied@redhat.com> | 2014-08-04 19:26:09 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2014-08-04 19:26:09 -0400 |
commit | 920f946428b70494eb1c64e0de260da0d8bde040 (patch) | |
tree | f858df3d40b2ef36b282949b7feaa82cd8b95e8a /drivers/gpu/drm/i2c | |
parent | eceb55a0ecd584ac5bebf667ffd8e859f261d0c0 (diff) | |
parent | c707c3619ca81f499a5ce032021405e989a96ff0 (diff) |
Merge branch 'tda998x-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-cubox into drm-next
This builds upon the previous set of fixes which were pulled on 6th July.
Included in this set are:
- an update from Jean-Francois to add the missing reg documentation entry
to the device tree documentation.
- conversion of the tda998x driver to the component helpers.
* 'tda998x-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-cubox:
drm/i2c: tda998x: add component support
drm/i2c: tda998x: allow re-use of tda998x support code
drm/i2c: tda998x: fix lack of required reg in DT documentation
Conflicts:
drivers/gpu/drm/i2c/tda998x_drv.c
Diffstat (limited to 'drivers/gpu/drm/i2c')
-rw-r--r-- | drivers/gpu/drm/i2c/tda998x_drv.c | 387 |
1 files changed, 306 insertions, 81 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index a8f1e03bd1f5..e9ddab93a9d8 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
@@ -15,8 +15,7 @@ | |||
15 | * this program. If not, see <http://www.gnu.org/licenses/>. | 15 | * this program. If not, see <http://www.gnu.org/licenses/>. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | 18 | #include <linux/component.h> | |
19 | |||
20 | #include <linux/hdmi.h> | 19 | #include <linux/hdmi.h> |
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
22 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
@@ -730,12 +729,9 @@ tda998x_configure_audio(struct tda998x_priv *priv, | |||
730 | 729 | ||
731 | /* DRM encoder functions */ | 730 | /* DRM encoder functions */ |
732 | 731 | ||
733 | static void | 732 | static void tda998x_encoder_set_config(struct tda998x_priv *priv, |
734 | tda998x_encoder_set_config(struct drm_encoder *encoder, void *params) | 733 | const struct tda998x_encoder_params *p) |
735 | { | 734 | { |
736 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
737 | struct tda998x_encoder_params *p = params; | ||
738 | |||
739 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | | 735 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(p->swap_a) | |
740 | (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | | 736 | (p->mirr_a ? VIP_CNTRL_0_MIRR_A : 0) | |
741 | VIP_CNTRL_0_SWAP_B(p->swap_b) | | 737 | VIP_CNTRL_0_SWAP_B(p->swap_b) | |
@@ -752,11 +748,8 @@ tda998x_encoder_set_config(struct drm_encoder *encoder, void *params) | |||
752 | priv->params = *p; | 748 | priv->params = *p; |
753 | } | 749 | } |
754 | 750 | ||
755 | static void | 751 | static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode) |
756 | tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
757 | { | 752 | { |
758 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
759 | |||
760 | /* we only care about on or off: */ | 753 | /* we only care about on or off: */ |
761 | if (mode != DRM_MODE_DPMS_ON) | 754 | if (mode != DRM_MODE_DPMS_ON) |
762 | mode = DRM_MODE_DPMS_OFF; | 755 | mode = DRM_MODE_DPMS_OFF; |
@@ -806,9 +799,8 @@ tda998x_encoder_mode_fixup(struct drm_encoder *encoder, | |||
806 | return true; | 799 | return true; |
807 | } | 800 | } |
808 | 801 | ||
809 | static int | 802 | static int tda998x_encoder_mode_valid(struct tda998x_priv *priv, |
810 | tda998x_encoder_mode_valid(struct drm_encoder *encoder, | 803 | struct drm_display_mode *mode) |
811 | struct drm_display_mode *mode) | ||
812 | { | 804 | { |
813 | if (mode->clock > 150000) | 805 | if (mode->clock > 150000) |
814 | return MODE_CLOCK_HIGH; | 806 | return MODE_CLOCK_HIGH; |
@@ -820,11 +812,10 @@ tda998x_encoder_mode_valid(struct drm_encoder *encoder, | |||
820 | } | 812 | } |
821 | 813 | ||
822 | static void | 814 | static void |
823 | tda998x_encoder_mode_set(struct drm_encoder *encoder, | 815 | tda998x_encoder_mode_set(struct tda998x_priv *priv, |
824 | struct drm_display_mode *mode, | 816 | struct drm_display_mode *mode, |
825 | struct drm_display_mode *adjusted_mode) | 817 | struct drm_display_mode *adjusted_mode) |
826 | { | 818 | { |
827 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
828 | uint16_t ref_pix, ref_line, n_pix, n_line; | 819 | uint16_t ref_pix, ref_line, n_pix, n_line; |
829 | uint16_t hs_pix_s, hs_pix_e; | 820 | uint16_t hs_pix_s, hs_pix_e; |
830 | uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; | 821 | uint16_t vs1_pix_s, vs1_pix_e, vs1_line_s, vs1_line_e; |
@@ -1012,20 +1003,16 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, | |||
1012 | } | 1003 | } |
1013 | 1004 | ||
1014 | static enum drm_connector_status | 1005 | static enum drm_connector_status |
1015 | tda998x_encoder_detect(struct drm_encoder *encoder, | 1006 | tda998x_encoder_detect(struct tda998x_priv *priv) |
1016 | struct drm_connector *connector) | ||
1017 | { | 1007 | { |
1018 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
1019 | uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV); | 1008 | uint8_t val = cec_read(priv, REG_CEC_RXSHPDLEV); |
1020 | 1009 | ||
1021 | return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : | 1010 | return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : |
1022 | connector_status_disconnected; | 1011 | connector_status_disconnected; |
1023 | } | 1012 | } |
1024 | 1013 | ||
1025 | static int | 1014 | static int read_edid_block(struct tda998x_priv *priv, uint8_t *buf, int blk) |
1026 | read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) | ||
1027 | { | 1015 | { |
1028 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
1029 | uint8_t offset, segptr; | 1016 | uint8_t offset, segptr; |
1030 | int ret, i; | 1017 | int ret, i; |
1031 | 1018 | ||
@@ -1079,10 +1066,8 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) | |||
1079 | return 0; | 1066 | return 0; |
1080 | } | 1067 | } |
1081 | 1068 | ||
1082 | static uint8_t * | 1069 | static uint8_t *do_get_edid(struct tda998x_priv *priv) |
1083 | do_get_edid(struct drm_encoder *encoder) | ||
1084 | { | 1070 | { |
1085 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
1086 | int j, valid_extensions = 0; | 1071 | int j, valid_extensions = 0; |
1087 | uint8_t *block, *new; | 1072 | uint8_t *block, *new; |
1088 | bool print_bad_edid = drm_debug & DRM_UT_KMS; | 1073 | bool print_bad_edid = drm_debug & DRM_UT_KMS; |
@@ -1094,7 +1079,7 @@ do_get_edid(struct drm_encoder *encoder) | |||
1094 | reg_clear(priv, REG_TX4, TX4_PD_RAM); | 1079 | reg_clear(priv, REG_TX4, TX4_PD_RAM); |
1095 | 1080 | ||
1096 | /* base block fetch */ | 1081 | /* base block fetch */ |
1097 | if (read_edid_block(encoder, block, 0)) | 1082 | if (read_edid_block(priv, block, 0)) |
1098 | goto fail; | 1083 | goto fail; |
1099 | 1084 | ||
1100 | if (!drm_edid_block_valid(block, 0, print_bad_edid)) | 1085 | if (!drm_edid_block_valid(block, 0, print_bad_edid)) |
@@ -1111,7 +1096,7 @@ do_get_edid(struct drm_encoder *encoder) | |||
1111 | 1096 | ||
1112 | for (j = 1; j <= block[0x7e]; j++) { | 1097 | for (j = 1; j <= block[0x7e]; j++) { |
1113 | uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; | 1098 | uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; |
1114 | if (read_edid_block(encoder, ext_block, j)) | 1099 | if (read_edid_block(priv, ext_block, j)) |
1115 | goto fail; | 1100 | goto fail; |
1116 | 1101 | ||
1117 | if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) | 1102 | if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) |
@@ -1144,11 +1129,10 @@ fail: | |||
1144 | } | 1129 | } |
1145 | 1130 | ||
1146 | static int | 1131 | static int |
1147 | tda998x_encoder_get_modes(struct drm_encoder *encoder, | 1132 | tda998x_encoder_get_modes(struct tda998x_priv *priv, |
1148 | struct drm_connector *connector) | 1133 | struct drm_connector *connector) |
1149 | { | 1134 | { |
1150 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | 1135 | struct edid *edid = (struct edid *)do_get_edid(priv); |
1151 | struct edid *edid = (struct edid *)do_get_edid(encoder); | ||
1152 | int n = 0; | 1136 | int n = 0; |
1153 | 1137 | ||
1154 | if (edid) { | 1138 | if (edid) { |
@@ -1161,18 +1145,14 @@ tda998x_encoder_get_modes(struct drm_encoder *encoder, | |||
1161 | return n; | 1145 | return n; |
1162 | } | 1146 | } |
1163 | 1147 | ||
1164 | static int | 1148 | static void tda998x_encoder_set_polling(struct tda998x_priv *priv, |
1165 | tda998x_encoder_create_resources(struct drm_encoder *encoder, | 1149 | struct drm_connector *connector) |
1166 | struct drm_connector *connector) | ||
1167 | { | 1150 | { |
1168 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
1169 | |||
1170 | if (priv->hdmi->irq) | 1151 | if (priv->hdmi->irq) |
1171 | connector->polled = DRM_CONNECTOR_POLL_HPD; | 1152 | connector->polled = DRM_CONNECTOR_POLL_HPD; |
1172 | else | 1153 | else |
1173 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | | 1154 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
1174 | DRM_CONNECTOR_POLL_DISCONNECT; | 1155 | DRM_CONNECTOR_POLL_DISCONNECT; |
1175 | return 0; | ||
1176 | } | 1156 | } |
1177 | 1157 | ||
1178 | static int | 1158 | static int |
@@ -1185,11 +1165,8 @@ tda998x_encoder_set_property(struct drm_encoder *encoder, | |||
1185 | return 0; | 1165 | return 0; |
1186 | } | 1166 | } |
1187 | 1167 | ||
1188 | static void | 1168 | static void tda998x_destroy(struct tda998x_priv *priv) |
1189 | tda998x_encoder_destroy(struct drm_encoder *encoder) | ||
1190 | { | 1169 | { |
1191 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
1192 | |||
1193 | /* disable all IRQs and free the IRQ handler */ | 1170 | /* disable all IRQs and free the IRQ handler */ |
1194 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); | 1171 | cec_write(priv, REG_CEC_RXSHPDINTENA, 0); |
1195 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); | 1172 | reg_clear(priv, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); |
@@ -1197,53 +1174,88 @@ tda998x_encoder_destroy(struct drm_encoder *encoder) | |||
1197 | free_irq(priv->hdmi->irq, priv); | 1174 | free_irq(priv->hdmi->irq, priv); |
1198 | 1175 | ||
1199 | i2c_unregister_device(priv->cec); | 1176 | i2c_unregister_device(priv->cec); |
1177 | } | ||
1178 | |||
1179 | /* Slave encoder support */ | ||
1180 | |||
1181 | static void | ||
1182 | tda998x_encoder_slave_set_config(struct drm_encoder *encoder, void *params) | ||
1183 | { | ||
1184 | tda998x_encoder_set_config(to_tda998x_priv(encoder), params); | ||
1185 | } | ||
1186 | |||
1187 | static void tda998x_encoder_slave_destroy(struct drm_encoder *encoder) | ||
1188 | { | ||
1189 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | ||
1190 | |||
1191 | tda998x_destroy(priv); | ||
1200 | drm_i2c_encoder_destroy(encoder); | 1192 | drm_i2c_encoder_destroy(encoder); |
1201 | kfree(priv); | 1193 | kfree(priv); |
1202 | } | 1194 | } |
1203 | 1195 | ||
1204 | static struct drm_encoder_slave_funcs tda998x_encoder_funcs = { | 1196 | static void tda998x_encoder_slave_dpms(struct drm_encoder *encoder, int mode) |
1205 | .set_config = tda998x_encoder_set_config, | 1197 | { |
1206 | .destroy = tda998x_encoder_destroy, | 1198 | tda998x_encoder_dpms(to_tda998x_priv(encoder), mode); |
1207 | .dpms = tda998x_encoder_dpms, | 1199 | } |
1208 | .save = tda998x_encoder_save, | ||
1209 | .restore = tda998x_encoder_restore, | ||
1210 | .mode_fixup = tda998x_encoder_mode_fixup, | ||
1211 | .mode_valid = tda998x_encoder_mode_valid, | ||
1212 | .mode_set = tda998x_encoder_mode_set, | ||
1213 | .detect = tda998x_encoder_detect, | ||
1214 | .get_modes = tda998x_encoder_get_modes, | ||
1215 | .create_resources = tda998x_encoder_create_resources, | ||
1216 | .set_property = tda998x_encoder_set_property, | ||
1217 | }; | ||
1218 | 1200 | ||
1219 | /* I2C driver functions */ | 1201 | static int tda998x_encoder_slave_mode_valid(struct drm_encoder *encoder, |
1202 | struct drm_display_mode *mode) | ||
1203 | { | ||
1204 | return tda998x_encoder_mode_valid(to_tda998x_priv(encoder), mode); | ||
1205 | } | ||
1220 | 1206 | ||
1221 | static int | 1207 | static void |
1222 | tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1208 | tda998x_encoder_slave_mode_set(struct drm_encoder *encoder, |
1209 | struct drm_display_mode *mode, | ||
1210 | struct drm_display_mode *adjusted_mode) | ||
1223 | { | 1211 | { |
1224 | return 0; | 1212 | tda998x_encoder_mode_set(to_tda998x_priv(encoder), mode, adjusted_mode); |
1213 | } | ||
1214 | |||
1215 | static enum drm_connector_status | ||
1216 | tda998x_encoder_slave_detect(struct drm_encoder *encoder, | ||
1217 | struct drm_connector *connector) | ||
1218 | { | ||
1219 | return tda998x_encoder_detect(to_tda998x_priv(encoder)); | ||
1220 | } | ||
1221 | |||
1222 | static int tda998x_encoder_slave_get_modes(struct drm_encoder *encoder, | ||
1223 | struct drm_connector *connector) | ||
1224 | { | ||
1225 | return tda998x_encoder_get_modes(to_tda998x_priv(encoder), connector); | ||
1225 | } | 1226 | } |
1226 | 1227 | ||
1227 | static int | 1228 | static int |
1228 | tda998x_remove(struct i2c_client *client) | 1229 | tda998x_encoder_slave_create_resources(struct drm_encoder *encoder, |
1230 | struct drm_connector *connector) | ||
1229 | { | 1231 | { |
1232 | tda998x_encoder_set_polling(to_tda998x_priv(encoder), connector); | ||
1230 | return 0; | 1233 | return 0; |
1231 | } | 1234 | } |
1232 | 1235 | ||
1233 | static int | 1236 | static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = { |
1234 | tda998x_encoder_init(struct i2c_client *client, | 1237 | .set_config = tda998x_encoder_slave_set_config, |
1235 | struct drm_device *dev, | 1238 | .destroy = tda998x_encoder_slave_destroy, |
1236 | struct drm_encoder_slave *encoder_slave) | 1239 | .dpms = tda998x_encoder_slave_dpms, |
1240 | .save = tda998x_encoder_save, | ||
1241 | .restore = tda998x_encoder_restore, | ||
1242 | .mode_fixup = tda998x_encoder_mode_fixup, | ||
1243 | .mode_valid = tda998x_encoder_slave_mode_valid, | ||
1244 | .mode_set = tda998x_encoder_slave_mode_set, | ||
1245 | .detect = tda998x_encoder_slave_detect, | ||
1246 | .get_modes = tda998x_encoder_slave_get_modes, | ||
1247 | .create_resources = tda998x_encoder_slave_create_resources, | ||
1248 | .set_property = tda998x_encoder_set_property, | ||
1249 | }; | ||
1250 | |||
1251 | /* I2C driver functions */ | ||
1252 | |||
1253 | static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) | ||
1237 | { | 1254 | { |
1238 | struct tda998x_priv *priv; | ||
1239 | struct device_node *np = client->dev.of_node; | 1255 | struct device_node *np = client->dev.of_node; |
1240 | u32 video; | 1256 | u32 video; |
1241 | int rev_lo, rev_hi, ret; | 1257 | int rev_lo, rev_hi, ret; |
1242 | 1258 | ||
1243 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1244 | if (!priv) | ||
1245 | return -ENOMEM; | ||
1246 | |||
1247 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); | 1259 | priv->vip_cntrl_0 = VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3); |
1248 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); | 1260 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); |
1249 | priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); | 1261 | priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); |
@@ -1251,17 +1263,11 @@ tda998x_encoder_init(struct i2c_client *client, | |||
1251 | priv->current_page = 0xff; | 1263 | priv->current_page = 0xff; |
1252 | priv->hdmi = client; | 1264 | priv->hdmi = client; |
1253 | priv->cec = i2c_new_dummy(client->adapter, 0x34); | 1265 | priv->cec = i2c_new_dummy(client->adapter, 0x34); |
1254 | if (!priv->cec) { | 1266 | if (!priv->cec) |
1255 | kfree(priv); | ||
1256 | return -ENODEV; | 1267 | return -ENODEV; |
1257 | } | ||
1258 | 1268 | ||
1259 | priv->encoder = &encoder_slave->base; | ||
1260 | priv->dpms = DRM_MODE_DPMS_OFF; | 1269 | priv->dpms = DRM_MODE_DPMS_OFF; |
1261 | 1270 | ||
1262 | encoder_slave->slave_priv = priv; | ||
1263 | encoder_slave->slave_funcs = &tda998x_encoder_funcs; | ||
1264 | |||
1265 | /* wake up the device: */ | 1271 | /* wake up the device: */ |
1266 | cec_write(priv, REG_CEC_ENAMODS, | 1272 | cec_write(priv, REG_CEC_ENAMODS, |
1267 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); | 1273 | CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); |
@@ -1364,12 +1370,231 @@ fail: | |||
1364 | */ | 1370 | */ |
1365 | if (priv->cec) | 1371 | if (priv->cec) |
1366 | i2c_unregister_device(priv->cec); | 1372 | i2c_unregister_device(priv->cec); |
1367 | kfree(priv); | ||
1368 | encoder_slave->slave_priv = NULL; | ||
1369 | encoder_slave->slave_funcs = NULL; | ||
1370 | return -ENXIO; | 1373 | return -ENXIO; |
1371 | } | 1374 | } |
1372 | 1375 | ||
1376 | static int tda998x_encoder_init(struct i2c_client *client, | ||
1377 | struct drm_device *dev, | ||
1378 | struct drm_encoder_slave *encoder_slave) | ||
1379 | { | ||
1380 | struct tda998x_priv *priv; | ||
1381 | int ret; | ||
1382 | |||
1383 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
1384 | if (!priv) | ||
1385 | return -ENOMEM; | ||
1386 | |||
1387 | priv->encoder = &encoder_slave->base; | ||
1388 | |||
1389 | ret = tda998x_create(client, priv); | ||
1390 | if (ret) { | ||
1391 | kfree(priv); | ||
1392 | return ret; | ||
1393 | } | ||
1394 | |||
1395 | encoder_slave->slave_priv = priv; | ||
1396 | encoder_slave->slave_funcs = &tda998x_encoder_slave_funcs; | ||
1397 | |||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | struct tda998x_priv2 { | ||
1402 | struct tda998x_priv base; | ||
1403 | struct drm_encoder encoder; | ||
1404 | struct drm_connector connector; | ||
1405 | }; | ||
1406 | |||
1407 | #define conn_to_tda998x_priv2(x) \ | ||
1408 | container_of(x, struct tda998x_priv2, connector); | ||
1409 | |||
1410 | #define enc_to_tda998x_priv2(x) \ | ||
1411 | container_of(x, struct tda998x_priv2, encoder); | ||
1412 | |||
1413 | static void tda998x_encoder2_dpms(struct drm_encoder *encoder, int mode) | ||
1414 | { | ||
1415 | struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); | ||
1416 | |||
1417 | tda998x_encoder_dpms(&priv->base, mode); | ||
1418 | } | ||
1419 | |||
1420 | static void tda998x_encoder_prepare(struct drm_encoder *encoder) | ||
1421 | { | ||
1422 | tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_OFF); | ||
1423 | } | ||
1424 | |||
1425 | static void tda998x_encoder_commit(struct drm_encoder *encoder) | ||
1426 | { | ||
1427 | tda998x_encoder2_dpms(encoder, DRM_MODE_DPMS_ON); | ||
1428 | } | ||
1429 | |||
1430 | static void tda998x_encoder2_mode_set(struct drm_encoder *encoder, | ||
1431 | struct drm_display_mode *mode, | ||
1432 | struct drm_display_mode *adjusted_mode) | ||
1433 | { | ||
1434 | struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); | ||
1435 | |||
1436 | tda998x_encoder_mode_set(&priv->base, mode, adjusted_mode); | ||
1437 | } | ||
1438 | |||
1439 | static const struct drm_encoder_helper_funcs tda998x_encoder_helper_funcs = { | ||
1440 | .dpms = tda998x_encoder2_dpms, | ||
1441 | .save = tda998x_encoder_save, | ||
1442 | .restore = tda998x_encoder_restore, | ||
1443 | .mode_fixup = tda998x_encoder_mode_fixup, | ||
1444 | .prepare = tda998x_encoder_prepare, | ||
1445 | .commit = tda998x_encoder_commit, | ||
1446 | .mode_set = tda998x_encoder2_mode_set, | ||
1447 | }; | ||
1448 | |||
1449 | static void tda998x_encoder_destroy(struct drm_encoder *encoder) | ||
1450 | { | ||
1451 | struct tda998x_priv2 *priv = enc_to_tda998x_priv2(encoder); | ||
1452 | |||
1453 | tda998x_destroy(&priv->base); | ||
1454 | drm_encoder_cleanup(encoder); | ||
1455 | } | ||
1456 | |||
1457 | static const struct drm_encoder_funcs tda998x_encoder_funcs = { | ||
1458 | .destroy = tda998x_encoder_destroy, | ||
1459 | }; | ||
1460 | |||
1461 | static int tda998x_connector_get_modes(struct drm_connector *connector) | ||
1462 | { | ||
1463 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
1464 | |||
1465 | return tda998x_encoder_get_modes(&priv->base, connector); | ||
1466 | } | ||
1467 | |||
1468 | static int tda998x_connector_mode_valid(struct drm_connector *connector, | ||
1469 | struct drm_display_mode *mode) | ||
1470 | { | ||
1471 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
1472 | |||
1473 | return tda998x_encoder_mode_valid(&priv->base, mode); | ||
1474 | } | ||
1475 | |||
1476 | static struct drm_encoder * | ||
1477 | tda998x_connector_best_encoder(struct drm_connector *connector) | ||
1478 | { | ||
1479 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
1480 | |||
1481 | return &priv->encoder; | ||
1482 | } | ||
1483 | |||
1484 | static | ||
1485 | const struct drm_connector_helper_funcs tda998x_connector_helper_funcs = { | ||
1486 | .get_modes = tda998x_connector_get_modes, | ||
1487 | .mode_valid = tda998x_connector_mode_valid, | ||
1488 | .best_encoder = tda998x_connector_best_encoder, | ||
1489 | }; | ||
1490 | |||
1491 | static enum drm_connector_status | ||
1492 | tda998x_connector_detect(struct drm_connector *connector, bool force) | ||
1493 | { | ||
1494 | struct tda998x_priv2 *priv = conn_to_tda998x_priv2(connector); | ||
1495 | |||
1496 | return tda998x_encoder_detect(&priv->base); | ||
1497 | } | ||
1498 | |||
1499 | static void tda998x_connector_destroy(struct drm_connector *connector) | ||
1500 | { | ||
1501 | drm_sysfs_connector_remove(connector); | ||
1502 | drm_connector_cleanup(connector); | ||
1503 | } | ||
1504 | |||
1505 | static const struct drm_connector_funcs tda998x_connector_funcs = { | ||
1506 | .dpms = drm_helper_connector_dpms, | ||
1507 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
1508 | .detect = tda998x_connector_detect, | ||
1509 | .destroy = tda998x_connector_destroy, | ||
1510 | }; | ||
1511 | |||
1512 | static int tda998x_bind(struct device *dev, struct device *master, void *data) | ||
1513 | { | ||
1514 | struct tda998x_encoder_params *params = dev->platform_data; | ||
1515 | struct i2c_client *client = to_i2c_client(dev); | ||
1516 | struct drm_device *drm = data; | ||
1517 | struct tda998x_priv2 *priv; | ||
1518 | int ret; | ||
1519 | |||
1520 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
1521 | if (!priv) | ||
1522 | return -ENOMEM; | ||
1523 | |||
1524 | dev_set_drvdata(dev, priv); | ||
1525 | |||
1526 | priv->base.encoder = &priv->encoder; | ||
1527 | priv->connector.interlace_allowed = 1; | ||
1528 | priv->encoder.possible_crtcs = 1 << 0; | ||
1529 | |||
1530 | ret = tda998x_create(client, &priv->base); | ||
1531 | if (ret) | ||
1532 | return ret; | ||
1533 | |||
1534 | if (!dev->of_node && params) | ||
1535 | tda998x_encoder_set_config(&priv->base, params); | ||
1536 | |||
1537 | tda998x_encoder_set_polling(&priv->base, &priv->connector); | ||
1538 | |||
1539 | drm_encoder_helper_add(&priv->encoder, &tda998x_encoder_helper_funcs); | ||
1540 | ret = drm_encoder_init(drm, &priv->encoder, &tda998x_encoder_funcs, | ||
1541 | DRM_MODE_ENCODER_TMDS); | ||
1542 | if (ret) | ||
1543 | goto err_encoder; | ||
1544 | |||
1545 | drm_connector_helper_add(&priv->connector, | ||
1546 | &tda998x_connector_helper_funcs); | ||
1547 | ret = drm_connector_init(drm, &priv->connector, | ||
1548 | &tda998x_connector_funcs, | ||
1549 | DRM_MODE_CONNECTOR_HDMIA); | ||
1550 | if (ret) | ||
1551 | goto err_connector; | ||
1552 | |||
1553 | ret = drm_sysfs_connector_add(&priv->connector); | ||
1554 | if (ret) | ||
1555 | goto err_sysfs; | ||
1556 | |||
1557 | priv->connector.encoder = &priv->encoder; | ||
1558 | drm_mode_connector_attach_encoder(&priv->connector, &priv->encoder); | ||
1559 | |||
1560 | return 0; | ||
1561 | |||
1562 | err_sysfs: | ||
1563 | drm_connector_cleanup(&priv->connector); | ||
1564 | err_connector: | ||
1565 | drm_encoder_cleanup(&priv->encoder); | ||
1566 | err_encoder: | ||
1567 | tda998x_destroy(&priv->base); | ||
1568 | return ret; | ||
1569 | } | ||
1570 | |||
1571 | static void tda998x_unbind(struct device *dev, struct device *master, | ||
1572 | void *data) | ||
1573 | { | ||
1574 | struct tda998x_priv2 *priv = dev_get_drvdata(dev); | ||
1575 | |||
1576 | drm_connector_cleanup(&priv->connector); | ||
1577 | drm_encoder_cleanup(&priv->encoder); | ||
1578 | tda998x_destroy(&priv->base); | ||
1579 | } | ||
1580 | |||
1581 | static const struct component_ops tda998x_ops = { | ||
1582 | .bind = tda998x_bind, | ||
1583 | .unbind = tda998x_unbind, | ||
1584 | }; | ||
1585 | |||
1586 | static int | ||
1587 | tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
1588 | { | ||
1589 | return component_add(&client->dev, &tda998x_ops); | ||
1590 | } | ||
1591 | |||
1592 | static int tda998x_remove(struct i2c_client *client) | ||
1593 | { | ||
1594 | component_del(&client->dev, &tda998x_ops); | ||
1595 | return 0; | ||
1596 | } | ||
1597 | |||
1373 | #ifdef CONFIG_OF | 1598 | #ifdef CONFIG_OF |
1374 | static const struct of_device_id tda998x_dt_ids[] = { | 1599 | static const struct of_device_id tda998x_dt_ids[] = { |
1375 | { .compatible = "nxp,tda998x", }, | 1600 | { .compatible = "nxp,tda998x", }, |