Rev 2997 | Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2997 | Rev 5078 | ||
---|---|---|---|
Line 28... | Line 28... | ||
28 | #include "atom.h" |
28 | #include "atom.h" |
Line 29... | Line 29... | ||
29 | 29 | ||
Line 30... | Line 30... | ||
30 | #define TARGET_HW_I2C_CLOCK 50 |
30 | #define TARGET_HW_I2C_CLOCK 50 |
31 | 31 | ||
32 | /* these are a limitation of ProcessI2cChannelTransaction not the hw */ |
32 | /* these are a limitation of ProcessI2cChannelTransaction not the hw */ |
Line 33... | Line 33... | ||
33 | #define ATOM_MAX_HW_I2C_WRITE 2 |
33 | #define ATOM_MAX_HW_I2C_WRITE 3 |
34 | #define ATOM_MAX_HW_I2C_READ 255 |
34 | #define ATOM_MAX_HW_I2C_READ 255 |
35 | 35 | ||
Line 40... | Line 40... | ||
40 | struct drm_device *dev = chan->dev; |
40 | struct drm_device *dev = chan->dev; |
41 | struct radeon_device *rdev = dev->dev_private; |
41 | struct radeon_device *rdev = dev->dev_private; |
42 | PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; |
42 | PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; |
43 | int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); |
43 | int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); |
44 | unsigned char *base; |
44 | unsigned char *base; |
- | 45 | u16 out = cpu_to_le16(0); |
|
45 | u16 out; |
46 | int r = 0; |
Line 46... | Line 47... | ||
46 | 47 | ||
Line -... | Line 48... | ||
- | 48 | memset(&args, 0, sizeof(args)); |
|
- | 49 | ||
47 | memset(&args, 0, sizeof(args)); |
50 | mutex_lock(&chan->mutex); |
Line 48... | Line 51... | ||
48 | 51 | ||
49 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; |
52 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; |
50 | 53 | ||
51 | if (flags & HW_I2C_WRITE) { |
54 | if (flags & HW_I2C_WRITE) { |
- | 55 | if (num > ATOM_MAX_HW_I2C_WRITE) { |
|
52 | if (num > ATOM_MAX_HW_I2C_WRITE) { |
56 | DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 3)\n", num); |
- | 57 | r = -EINVAL; |
|
- | 58 | goto done; |
|
- | 59 | } |
|
- | 60 | if (buf == NULL) |
|
- | 61 | args.ucRegIndex = 0; |
|
- | 62 | else |
|
- | 63 | args.ucRegIndex = buf[0]; |
|
53 | DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num); |
64 | if (num) |
54 | return -EINVAL; |
65 | num--; |
55 | } |
66 | if (num) |
56 | memcpy(&out, buf, num); |
67 | memcpy(&out, &buf[1], num); |
57 | args.lpI2CDataOut = cpu_to_le16(out); |
68 | args.lpI2CDataOut = cpu_to_le16(out); |
58 | } else { |
69 | } else { |
- | 70 | if (num > ATOM_MAX_HW_I2C_READ) { |
|
59 | if (num > ATOM_MAX_HW_I2C_READ) { |
71 | DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); |
- | 72 | r = -EINVAL; |
|
- | 73 | goto done; |
|
60 | DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); |
74 | } |
Line -... | Line 75... | ||
- | 75 | args.ucRegIndex = 0; |
|
61 | return -EINVAL; |
76 | args.lpI2CDataOut = 0; |
62 | } |
- | |
63 | } |
77 | } |
64 | 78 | ||
65 | args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; |
79 | args.ucFlag = flags; |
Line 66... | Line 80... | ||
66 | args.ucRegIndex = 0; |
80 | args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; |
Line 67... | Line 81... | ||
67 | args.ucTransBytes = num; |
81 | args.ucTransBytes = num; |
68 | args.ucSlaveAddr = slave_addr << 1; |
82 | args.ucSlaveAddr = slave_addr << 1; |
69 | args.ucLineNumber = chan->rec.i2c_id; |
83 | args.ucLineNumber = chan->rec.i2c_id; |
70 | 84 | ||
- | 85 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
|
71 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
86 | |
Line 72... | Line 87... | ||
72 | 87 | /* error */ |
|
73 | /* error */ |
88 | if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { |
- | 89 | DRM_DEBUG_KMS("hw_i2c error\n"); |
|
- | 90 | r = -EIO; |
|
- | 91 | goto done; |
|
Line 74... | Line 92... | ||
74 | if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { |
92 | } |
75 | DRM_DEBUG_KMS("hw_i2c error\n"); |
93 | |
Line 76... | Line 94... | ||
76 | return -EIO; |
94 | if (!(flags & HW_I2C_WRITE)) |
77 | } |
95 | radeon_atom_copy_swap(buf, base, num, false); |
78 | 96 | ||
79 | if (!(flags & HW_I2C_WRITE)) |
97 | done: |
80 | memcpy(buf, base, num); |
98 | mutex_unlock(&chan->mutex); |
81 | 99 | ||
82 | return 0; |
100 | return r; |
Line 83... | Line 101... | ||
83 | } |
101 | } |
84 | 102 | ||
85 | int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, |
103 | int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, |
86 | struct i2c_msg *msgs, int num) |
104 | struct i2c_msg *msgs, int num) |
87 | { |
105 | { |
88 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); |
106 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); |
89 | struct i2c_msg *p; |
107 | struct i2c_msg *p; |
90 | int i, remaining, current_count, buffer_offset, max_bytes, ret; |
108 | int i, remaining, current_count, buffer_offset, max_bytes, ret; |
91 | u8 buf = 0, flags; |
109 | u8 flags; |
92 | 110 | ||
93 | /* check for bus probe */ |
111 | /* check for bus probe */ |