| | 837 | for (i = 0; i < 7; i++) { |
| | 838 | if (!(data->has_fan & (1 << i))) |
| | 839 | continue; |
| | 840 | if (data->fan[i] == 0xff && data->fan_div[i] < 7) |
| | 841 | w83792d_set_fan_div(client, i, 7); |
| | 842 | else if (data->fan[i] < 0x70 && data->fan_div[i] > 0) { |
| | 843 | w83792d_set_fan_div(client, i, |
| | 844 | data->fan_div[i] - 1); |
| | 845 | } else if (data->fan[i] > 0xf8 && |
| | 846 | data->fan_div[i] < 7) { |
| | 847 | w83792d_set_fan_div(client, i, |
| | 848 | data->fan_div[i] + 1); |
| | 849 | } |
| | 850 | } |
| | 851 | |
| | 1021 | static void w83792d_set_fan_div(struct i2c_client *client, int nr, u8 newdiv) |
| | 1022 | { |
| | 1023 | struct w83792d_data *data = client->data; |
| | 1024 | int min = 0; |
| | 1025 | int old = 0; |
| | 1026 | u8 tmp = 0; |
| | 1027 | |
| | 1028 | newdiv = SENSORS_LIMIT(newdiv, 0, 7); |
| | 1029 | |
| | 1030 | if (newdiv == data->fan_div[nr]) { |
| | 1031 | return; |
| | 1032 | } |
| | 1033 | |
| | 1034 | min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); |
| | 1035 | old = FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr])); |
| | 1036 | data->fan_div[nr] = newdiv; |
| | 1037 | tmp = w83792d_read_value(client, W83792D_REG_FAN_DIV[nr >> 1]); |
| | 1038 | tmp &= (nr & 1) ? 0x8f : 0xf8; |
| | 1039 | tmp |= (nr & 1) ? ((newdiv << 4) & 0x70) : (newdiv & 0x07); |
| | 1040 | w83792d_write_value(client, W83792D_REG_FAN_DIV[nr >> 1], tmp); |
| | 1041 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
| | 1042 | data->fan[nr] = FAN_TO_REG(old, DIV_FROM_REG(data->fan_div[nr])); |
| | 1043 | w83792d_write_value(client, W83792D_REG_FAN_MIN[nr], |
| | 1044 | data->fan_min[nr]); |
| | 1045 | } |
| | 1046 | |
| 1018 | | DIV_FROM_REG(data->fan_div[nr])); |
| 1019 | | /* adjust Fan Divisor, then change RPM */ |
| 1020 | | do { |
| 1021 | | w83792d_update_client(client); |
| 1022 | | if ((data->fan[nr]>0x50) && (data->fan[nr]<0xff)) { |
| 1023 | | /* optimal case. 0x50 and 0xff are experience data */ |
| 1024 | | results[1] = FAN_FROM_REG(data->fan[nr], |
| 1025 | | DIV_FROM_REG(data->fan_div[nr])); |
| 1026 | | break; /* go out of the do-while loop. */ |
| 1027 | | } else { |
| 1028 | | if (((data->fan_div[nr])>=0x07 && |
| 1029 | | (data->fan[nr])==0xff) || |
| 1030 | | ((data->fan_div[nr])<=0 && |
| 1031 | | (data->fan[nr])<0x78)) { |
| 1032 | | results[1] = 0; |
| 1033 | | break; |
| 1034 | | } else if ((data->fan_div[nr])<0x07 && |
| 1035 | | (data->fan[nr])==0xff) { |
| 1036 | | (data->fan_div[nr])++; |
| 1037 | | results[1] = FAN_FROM_REG(data->fan[nr], |
| 1038 | | DIV_FROM_REG(data->fan_div[nr])); |
| 1039 | | } else if ((data->fan_div[nr])>0 && |
| 1040 | | (data->fan[nr])<0x78) { |
| 1041 | | (data->fan_div[nr])--; |
| 1042 | | results[1] = FAN_FROM_REG(data->fan[nr], |
| 1043 | | DIV_FROM_REG(data->fan_div[nr])); |
| 1044 | | } |
| 1045 | | |
| 1046 | | tmp_reg = w83792d_read_value(client, |
| 1047 | | W83792D_REG_FAN_DIV[nr/2]); |
| 1048 | | tmp_reg &= (nr%2 == 0) ? 0xf8 : 0x8f; |
| 1049 | | tmp_fan_div = (nr%2 == 0) ? (data->fan_div[nr]) |
| 1050 | | : (((data->fan_div[nr])<<4)&0x70); |
| 1051 | | w83792d_write_value(client, |
| 1052 | | W83792D_REG_FAN_DIV[nr/2], |
| 1053 | | tmp_reg|tmp_fan_div); |
| 1054 | | } |
| 1055 | | } while (0); |
| | 1060 | DIV_FROM_REG(data->fan_div[nr])); |
| | 1061 | results[1] = FAN_FROM_REG(data->fan[nr], |
| | 1062 | DIV_FROM_REG(data->fan_div[nr])); |
| | 1063 | if (!(data->has_fan & (1 << nr))) { |
| | 1064 | results[0] = 0; |
| | 1065 | results[1] = 0; |
| | 1066 | } |
| 1198 | | } else if (operation == SENSORS_PROC_REAL_WRITE) { |
| 1199 | | if (*nrels_mag < 7) { |
| 1200 | | return; |
| 1201 | | } |
| 1202 | | for (i=0; i<7; i++) { |
| 1203 | | temp_reg = SENSORS_LIMIT(results[i], 1, 128); |
| 1204 | | for (k=0,j=0; j<7; j++) { |
| 1205 | | temp_reg = temp_reg>>1; |
| 1206 | | if (temp_reg == 0) |
| 1207 | | break; |
| 1208 | | k++; |
| 1209 | | } |
| 1210 | | fan_div_reg = w83792d_read_value(client, |
| 1211 | | W83792D_REG_FAN_DIV[i/2]); |
| 1212 | | fan_div_reg &= (i%2 == 0) ? 0xf8 : 0x8f; |
| 1213 | | tmp_fan_div = (i%2 == 0) ? (k&0x07) |
| 1214 | | : ((k<<4)&0x70); |
| 1215 | | w83792d_write_value(client, |
| 1216 | | W83792D_REG_FAN_DIV[i/2], |
| 1217 | | fan_div_reg|tmp_fan_div); |
| 1218 | | } |