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 <drm/drm_managed.h>
0025 #include <drm/drm_print.h>
0026
0027 #include "ast_drv.h"
0028
0029 static void ast_i2c_setsda(void *i2c_priv, int data)
0030 {
0031 struct ast_i2c_chan *i2c = i2c_priv;
0032 struct ast_private *ast = to_ast_private(i2c->dev);
0033 int i;
0034 u8 ujcrb7, jtemp;
0035
0036 for (i = 0; i < 0x10000; i++) {
0037 ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
0038 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
0039 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
0040 if (ujcrb7 == jtemp)
0041 break;
0042 }
0043 }
0044
0045 static void ast_i2c_setscl(void *i2c_priv, int clock)
0046 {
0047 struct ast_i2c_chan *i2c = i2c_priv;
0048 struct ast_private *ast = to_ast_private(i2c->dev);
0049 int i;
0050 u8 ujcrb7, jtemp;
0051
0052 for (i = 0; i < 0x10000; i++) {
0053 ujcrb7 = ((clock & 0x01) ? 0 : 1);
0054 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
0055 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
0056 if (ujcrb7 == jtemp)
0057 break;
0058 }
0059 }
0060
0061 static int ast_i2c_getsda(void *i2c_priv)
0062 {
0063 struct ast_i2c_chan *i2c = i2c_priv;
0064 struct ast_private *ast = to_ast_private(i2c->dev);
0065 uint32_t val, val2, count, pass;
0066
0067 count = 0;
0068 pass = 0;
0069 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
0070 do {
0071 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
0072 if (val == val2) {
0073 pass++;
0074 } else {
0075 pass = 0;
0076 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
0077 }
0078 } while ((pass < 5) && (count++ < 0x10000));
0079
0080 return val & 1 ? 1 : 0;
0081 }
0082
0083 static int ast_i2c_getscl(void *i2c_priv)
0084 {
0085 struct ast_i2c_chan *i2c = i2c_priv;
0086 struct ast_private *ast = to_ast_private(i2c->dev);
0087 uint32_t val, val2, count, pass;
0088
0089 count = 0;
0090 pass = 0;
0091 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
0092 do {
0093 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
0094 if (val == val2) {
0095 pass++;
0096 } else {
0097 pass = 0;
0098 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
0099 }
0100 } while ((pass < 5) && (count++ < 0x10000));
0101
0102 return val & 1 ? 1 : 0;
0103 }
0104
0105 static void ast_i2c_release(struct drm_device *dev, void *res)
0106 {
0107 struct ast_i2c_chan *i2c = res;
0108
0109 i2c_del_adapter(&i2c->adapter);
0110 kfree(i2c);
0111 }
0112
0113 struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev)
0114 {
0115 struct ast_i2c_chan *i2c;
0116 int ret;
0117
0118 i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL);
0119 if (!i2c)
0120 return NULL;
0121
0122 i2c->adapter.owner = THIS_MODULE;
0123 i2c->adapter.class = I2C_CLASS_DDC;
0124 i2c->adapter.dev.parent = dev->dev;
0125 i2c->dev = dev;
0126 i2c_set_adapdata(&i2c->adapter, i2c);
0127 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
0128 "AST i2c bit bus");
0129 i2c->adapter.algo_data = &i2c->bit;
0130
0131 i2c->bit.udelay = 20;
0132 i2c->bit.timeout = 2;
0133 i2c->bit.data = i2c;
0134 i2c->bit.setsda = ast_i2c_setsda;
0135 i2c->bit.setscl = ast_i2c_setscl;
0136 i2c->bit.getsda = ast_i2c_getsda;
0137 i2c->bit.getscl = ast_i2c_getscl;
0138 ret = i2c_bit_add_bus(&i2c->adapter);
0139 if (ret) {
0140 drm_err(dev, "Failed to register bit i2c\n");
0141 goto out_kfree;
0142 }
0143
0144 ret = drmm_add_action_or_reset(dev, ast_i2c_release, i2c);
0145 if (ret)
0146 return NULL;
0147 return i2c;
0148
0149 out_kfree:
0150 kfree(i2c);
0151 return NULL;
0152 }